home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / stut_src / arbotree.c < prev    next >
C/C++ Source or Header  |  1996-05-26  |  80KB  |  3,189 lines

  1. /*
  2.  * treeedit.c
  3.  *
  4.  * Purpose:
  5.  * --------
  6.  * Fonctions permettant l'edition de l'arbre "arborescence":
  7.  *
  8.  * History:
  9.  * --------
  10.  * 18.05.94: Created by flanque, extracted from arboedit.c
  11.  */
  12.  
  13.     #include "!OPTIONS.H"                /* Options de compilation */         
  14.     #define    THIS_FILE    "ARBOTREE.C v1.02 - 03.95"
  15.           
  16. /*
  17.  * System headers:
  18.  */
  19.     #include    <stdio.h>
  20.     #include <stdlib.h>                    /* Malloc etc... */
  21.     #include    <string.h>                    /* Memcpy etc... */
  22.     #include    <aes.h>                        /* header AES */  
  23.     
  24. /*
  25.  * Custom headers:
  26.  */
  27.     #include    "SPEC_PU.H"
  28.     #include "S_MALLOC.H"
  29.     #include "STUT_ONE.RSC\STUT_3.H"                    /* noms des objets ds le ressource */
  30.     #include "AESDEF.H"
  31.     #include "EXFRM_PU.H"
  32.     #include "ATREE_PU.H"
  33.     #include "ARBPG_PU.H"
  34.     #include "ARPAR_PU.H"
  35.     #include "ARBKEYPU.H"
  36.     #include "DTDIR_PU.H"
  37.     #include "DATPG_PU.H"
  38.     #include    "DEBUG_PU.H"    
  39.     #include    "DESK_PU.H"    
  40.     #include    "MAIN_PU.H"    
  41.     #include "OBJCT_PU.H"
  42.     #include "RTERR_PU.H"
  43.     #include "VDI_PU.H"
  44.     #include "WIN_PU.H"                    /* Gestion des fenˆtres */
  45.     #include "WINDR_PU.H"    
  46.  
  47. /* 
  48.  * Headers ressource: 
  49.  */
  50.     #include    "ARBO.RCH"                /* Ressources d'‚dition arbo */
  51.     #include    "ARBO_MED.RCH"            /* Ressources d'‚dition arbo */
  52.  
  53.  
  54. /*
  55.  * ------------------------ PROTOTYPES -------------------------
  56.  */
  57.  
  58. /*
  59.  * PRIVate internal prototypes:
  60.  */
  61.     static    void    build_arbodir( DATADIR * *curr_datadir, OBJECT * *tree );
  62.     static    void    build_arbotree( DATADIR *curr_datadir, OBJECT * *tree );
  63.     static    OBJECT    *add_arbo_elt( OBJECT    *tree, OBJECT *srce_object, unsigned *nb_objs );
  64.  
  65.     static    int    drag_arboicon( unsigned object_id, int ob_x, int ob_y, 
  66.                                         int start_x, int start_y, 
  67.                                         int            n_GridSrceX,    /* In: Coordonn‚es de d‚part ds la grille */
  68.                                         int            n_GridSrceY,
  69.                                         int *drop_x, int *drop_y,
  70.                                         int             take_control );    /* In: faut il prendre le controle de l'‚cran ou pas? */
  71.     static    void    control_links( unsigned object_id,
  72.                                             int         pos_x,         /* In: Position propos‚e */
  73.                                             int         pos_y, 
  74.                                             int        n_StartX,    /* In: Position initiale */
  75.                                             int        n_StartY,
  76.                                             int *line_style );
  77.     static    int    iblk_owner( OBJECT *tree, int obj );
  78.     
  79.     static    DATAPAGE    *find_arbo_by_xy( DATADIR *datadir, int pos_x, int pos_y );
  80.     static    int    find_inlinkXY(                 /* Out: !=0 si non trouv‚ (erreur) */        
  81.                             DATADIR    * pDataDir,        /* In:  Datadir dans lequel on cherche */
  82.                             int        * pn_posX,        /* Out: Position X en cases */
  83.                             int        * pn_posY );    /* Out: Position Y en cases */
  84.  
  85.     static    void    link_arbo_to_parent( DATADIR *datadir, int pos_x, int pos_y );
  86.     static    unsigned    find_ascent(                     /* Out: Contenu de la cellule parent */
  87.                     DATADIR *    datadir,     /* In:  Dossier dans lequel on cherche */
  88.                     int             pos_x,         /* In:  Position de l'enfant */
  89.                     int             pos_y, 
  90.                     int *            ascent_x,     /* Out: Position du parent (meme si case vide) */
  91.                     int *            ascent_y );
  92.     static    void    find_children( DATADIR *datadir, int pos_x, int pos_y );
  93.     static    void    walk_arbotree( int pos_x, int pos_y );
  94.  
  95.     static    int arboTree_DeleteElt( 
  96.                             DATADIR    *    datadir,
  97.                             int            stcl_x,                /* In: Coordonn‚es dans le tableau */
  98.                             int            stcl_y,
  99.                             WIPARAMS *    wi_params_adr );
  100.  
  101. /*
  102.  * ------------------------ VARIABLES -------------------------
  103.  */
  104.  
  105. /*
  106.  * External variables: 
  107.  */
  108.     /* 
  109.      * Bureau: 
  110.      */
  111.     extern    OBJECT    *    G_desktop_adr;        /* Ptr sur arbre bureau */
  112.     extern    WIPARAMS    *    G_desk_params_adr;    /* ParamŠtres de la "fenˆtre bureau" */
  113.     /* 
  114.      * G‚n‚ral: 
  115.      */
  116.     extern    WIPARAMS    *    G_wi_list_adr;        /* Adresse de l'arbre de paramŠtres */
  117.     extern    int            G_x_mini, G_y_mini;    /* Coord sup gauche de l'‚cran */
  118.     extern    int            G_w_maxi, G_h_maxi;    /* Taille de l'‚cran de travail */
  119.     extern    int            G_top_wi_handle;        /* Fenˆtre g‚r‚e par le programme
  120.                                                             la plus en haut, mais pouvant ˆtre
  121.                                                             surpass‚e par un accessoire */
  122.     extern    char        *    G_empty_string;        /* Chaine vide */
  123.     extern    char        *    G_tmp_buffer;            /* Tampon */
  124.     /* 
  125.      * VDI: 
  126.      */
  127.     extern    int            G_ws_handle;            /* handle virtual workstation VDI */
  128.     extern    int           G_pxyarray[18];        /* Liste de coord X,Y pour le VDI */
  129.     extern    int            G_pxyarray2[10];    
  130.     extern    int            G_cliparray[ 4 ];
  131.     extern    USERBLK        G_bcroix_ublk;            /* Pour bouton-croix */
  132.     /* 
  133.      * Groupes de donn‚es: 
  134.      */
  135.     extern    DATAGROUP    *G_datagroups;        /* Pointeur sur tableau de G_datagroups */
  136.  
  137.  
  138. /*
  139.  * Public variables: 
  140.  */
  141.     /* 
  142.      * Dimensions des ic“nes: 
  143.      */
  144.      int        G_arbocell_w;                    /* Larg d'une ic“ne arbo */
  145.     int        G_arbocell_h;                    /* Hauteur... */
  146.  
  147.  
  148. /*
  149.  * Internal variables: 
  150.  */
  151.     /* 
  152.      * Arbres: 
  153.      */
  154.     static    OBJECT    *M_newlink_adr;            /* Nouveaux liens */
  155.     static    OBJECT    *M_newpagearbo_adr;        /* Nouvelles pages arbo */
  156.     /* 
  157.      * Objets pour arborescence: 
  158.      */
  159.     static    OBJECT    *M_arbotree;                /* Arbre arborescence */
  160.     static    USERBLK    M_grid_ublk = {    draw_grid,     /* Adr routine */
  161.                                                     0L };            /* Ob SPEC */    
  162.     static     int        M_arboelt_w;                    /* Larg d'une ic“ne arbo */
  163.     static    int        M_arboelt_h;                    /* Hauteur... */
  164.     static    int        M_fantome_lien[10];            /* Infos pour dessin du fant“me */
  165.     /* 
  166.      * Tableau des IDS associ‚s aux liens: 
  167.      */
  168.     static    int        M_link_id[]=
  169.     {
  170.         IDLINK_FETS,        /* Lien */
  171.         IDLINK_FETWS,        /* Lien */
  172.         IDLINK_FNTWSE,        /* Lien */
  173.         IDLINK_FWTSE,        /* Lien */
  174.         IDLINK_FWTS,        /* Lien */
  175.         IDLINK_FNTWS,        /* Lien */
  176.         IDLINK_FNTS,        /* Lien */
  177.         IDLINK_FNTSE,        /* Lien */
  178.         IDLINK_FNTW,        /* Lien */
  179.         IDLINK_FETW,        /* Lien */
  180.         IDLINK_FNTWE,        /* Lien */
  181.         IDLINK_FWTE,        /* Lien */
  182.         IDLINK_FNTE         /* Lien */
  183.     };
  184.     /* 
  185.      * Fonctions arbo: 
  186.      */
  187.     static    AFNCTSPEC        M_fnctarbo[]=
  188.     {
  189.         FA_MENU,                ARBOMENU,    "Menu, Ecran simple",
  190.         FA_ECRI_MSG,        AECRIMSG,    "Ecriture d'un message",
  191.         FA_LECT_MSG,        ALECTMSG,    "Lecture de message(s)",
  192.         FA_DISP_TEXT,        DISPTEXT,    "Affichage d'un texte",
  193.         FA_ID,                ARBOID,        "Identification User",
  194.         FA_NEW_ACCOUNT,    ARBONACC,    "Nouveau Compte User",
  195.         FA_LIST,                ARBOLIST,    "Liste de messages",
  196.         FA_DIRECTORY,        ARBODIR,     "Annuaire des comptes",
  197.         FA_FILESEL,            ARBOFSEL,    "S‚lection fichier",
  198.         FA_DOWNLOAD,        ARBODWLD,    "Download"
  199.     };
  200.     /*
  201.      * Liens IN par d‚faut:
  202.      */
  203. #include "FN_INLNK.C"
  204.     /* 
  205.      * Walking trees: 
  206.      */
  207.     static DATADIR     *    M_walker_datadir;
  208.     static unsigned    M_walker_mapwidth;
  209.     static unsigned *    M_walker_map;
  210.  
  211. /*
  212.  * ------------------------ FUNCTIONS -------------------------
  213.  */
  214.  
  215. /*
  216.  * init_tree(-)
  217.  *
  218.  * Purpose:
  219.  * --------
  220.  * Init de la gestion d'arborescence
  221.  *
  222.  * History:
  223.  * --------
  224.  * 1993: fplanque: Created
  225.  * 18.05.94: divis‚
  226.  * 02.02.95: gŠre moyenne r‚solution
  227.  * 13.02.95: d‚termine taille des ic“nes selon taille BITBLK d'un lien NORTH to SOUTH
  228.  */
  229. void    init_tree( void )
  230. {
  231.     TRACE0( "Initializing " THIS_FILE );
  232.  
  233.     /*
  234.      * Trouve adresses des arbres d'objets 
  235.      * (diff‚rentes selon qu'on est en moyenne ou haute r‚solution)
  236.      */
  237.     #if ACCEPT_SMALLFONTS
  238.         if( G_cell_size_prop == 1 )
  239.         {    /*
  240.              * Moyenne r‚solution
  241.              */
  242.             if( rsrc_gaddr( R_TREE, NEWLMED,  &M_newlink_adr ) == 0)
  243.                 erreur_rsrc();
  244.             if( rsrc_gaddr( R_TREE, NEWPAMED, &M_newpagearbo_adr ) == 0)
  245.                 erreur_rsrc();
  246.             M_arbotree = &rs_object_med[ 0 ];
  247.         }
  248.         else
  249.         {    /*
  250.              * haute
  251.              */
  252.             if( rsrc_gaddr( R_TREE, NEWLINK,  &M_newlink_adr ) == 0)
  253.                 erreur_rsrc();
  254.             if( rsrc_gaddr( R_TREE, NEWPAGEA, &M_newpagearbo_adr ) == 0)
  255.                 erreur_rsrc();
  256.             M_arbotree = &rs_object_hi[ 0 ];
  257.         }
  258.     #else
  259.         /*
  260.          * On peut consid‚rer qu'on est en haute:
  261.          */
  262.         if( rsrc_gaddr( R_TREE, NEWLINK,  &M_newlink_adr ) == 0)
  263.             erreur_rsrc();
  264.         if( rsrc_gaddr( R_TREE, NEWPAGEA, &M_newpagearbo_adr ) == 0)
  265.             erreur_rsrc();
  266.         M_arbotree = &rs_object_hi[ 0 ];
  267.     #endif        
  268.  
  269.     rsrc_color( M_newlink_adr );            /* Fixe couleurs */
  270.     rsrc_color( M_newpagearbo_adr );        /* Fixe couleurs */
  271.  
  272.  
  273.     /*
  274.      * Dimensions des ic“nes/liens arbo: 
  275.      */
  276.     M_arboelt_w = M_newlink_adr[ LKFNTS ] .ob_spec.bitblk -> bi_wb *8 -1;
  277.     M_arboelt_h = M_newlink_adr[ LKFNTS ] .ob_spec.bitblk -> bi_hl;
  278.     TRACE2( "  Size of arboelt= %d %d", M_arboelt_w, M_arboelt_h );
  279.     
  280.     /*
  281.      * Dimension de l'emplacement: 
  282.      */
  283.     G_arbocell_w = M_arboelt_w +1;        /* 47 -> 48 */
  284.     G_arbocell_h = M_arboelt_h +1;        /* 47 -> 48 */
  285.     TRACE2( "  Size of arbocell= %d %d", G_arbocell_w, G_arbocell_h );
  286.  
  287.     /* 
  288.      * Fant“me d'une ic“ne-LIEN: 
  289.      */
  290.     M_fantome_lien[ 0 ] = 0;
  291.     M_fantome_lien[ 1 ] = 0;
  292.     
  293.     M_fantome_lien[ 2 ] = M_arboelt_w-1;
  294.     M_fantome_lien[ 3 ] = 0;
  295.     
  296.     M_fantome_lien[ 4 ] = M_arboelt_w-1;
  297.     M_fantome_lien[ 5 ] = M_arboelt_h-1;
  298.     
  299.     M_fantome_lien[ 6 ] = 0;
  300.     M_fantome_lien[ 7 ] = M_arboelt_h-1;
  301.     
  302.     M_fantome_lien[ 8 ] = 0;
  303.     M_fantome_lien[ 9 ] = 1;                /* Pour ne pas se mordre la queue! */ 
  304.     
  305.     /*
  306.      * Param USERDEF: 
  307.      */
  308.     M_grid_ublk .ub_parm = M_arbotree -> ob_spec.index;    /* Copie OB_SPEC */
  309.     M_arbotree -> ob_spec.userblk = &M_grid_ublk;            /* Fixe adr USERBLK */
  310.  
  311.     /*
  312.      * Cr‚e modŠles de liens-IN:
  313.      */
  314.     M_in_arbolinks = CmdList_Create( M_inlinks );
  315.  
  316. }
  317.  
  318.  
  319.  
  320. /*
  321.  * open_arbotree(-)
  322.  *
  323.  * Purpose:
  324.  * --------
  325.  * Ouverture d'une fenˆtre sur un dossier de l'arborescence
  326.  *
  327.  * Algorythm:
  328.  * ----------  
  329.  *
  330.  * Notes:
  331.  * ------
  332.  * ATTENTION: la gestion des dossiers ARBO et des normaux ne se fait
  333.  * Pas de la mˆme maniŠre
  334.  *
  335.  * History:
  336.  * --------
  337.  * 1993: fplanque: Created
  338.  * 17.05.94: Centrage du lien in au milieu de la fenˆtre lors de son ouverture
  339.  * 08.08.94: fplanque: modif de la signalisation de MODIF sur le directory
  340.  * 21.09.94: modif gestion du nbre de dirs simultan‚s ouverts
  341.  */
  342. void open_arbotree( 
  343.             WIPARAMS *wi_params_adr )
  344. {
  345.     OBJECT        *tree;            /* Arbre d'objets */
  346.     DATAGROUP    *curr_datagr  = wi_params_adr -> datagroup;    /* Datagroup concern‚ */
  347.     DATADIR        *curr_datadir = wi_params_adr -> datadir;
  348.     int            n_posX, n_posY;
  349.  
  350.     /*
  351.      * Teste si le directory est vierge ou non: 
  352.      */
  353.     if( curr_datadir != NULL )
  354.     {    /********************************************/
  355.         /* Si on re-ouvre un dossier existant d‚j…: */
  356.         /********************************************/
  357.  
  358.         /*
  359.          * Contr“le si une fenˆtre est d‚j… ouverte sur le MEME dossier: 
  360.          */
  361.         if ( curr_datadir -> nb_dirs > 0 )
  362.         {    /*
  363.               * ----------------------------------------------------------
  364.              * Si il y a d‚j… une/des fenˆtres ouvertes sur ce dossier: 
  365.              * ----------------------------------------------------------
  366.              *
  367.              * On va r‚cup‚rer le contenu d'une fenˆtre: (avant on dupliquait!) 
  368.              *
  369.              * Etant donn‚ que les wi_params de la nlle fenˆtre ne sont pas   
  370.              *    encore pr‚sentes dans la liste, on peut demander une recherche
  371.              *    d'une AUTRE fenˆtre pointant sur le mˆme dataDIR:
  372.              */
  373.             WIPARAMS *modele_adr = find_datawindow2( (unsigned long) curr_datadir, G_wi_list_adr );
  374.             
  375.             /*
  376.              * R‚cupŠre Adresse de l'arbre d'objets de la premiŠre fenetre: 
  377.              */
  378.             tree = modele_adr -> draw_ptr.tree;
  379.         }
  380.         else
  381.         {    /*--------------------------------------------------*/
  382.             /* Si pas encore de fenˆtre ouverte sur ce dossier: */
  383.             /*--------------------------------------------------*/
  384.             /*
  385.              * On cr‚e juste un arbre d'objets selon les indications du DATDIR: 
  386.              */
  387.             build_arbotree( curr_datadir, &tree );
  388.         }
  389.     }
  390.     else
  391.     {    /**********************************/
  392.         /* Si on ouvre un dossier vierge: */
  393.         /**********************************/    
  394.         /*
  395.          * On cr‚e un dossier de contenu vierge: 
  396.          */
  397.  
  398.         /*
  399.          * Cr‚e les infos datadir 
  400.          * ainsi que l'arbre d'objets (simpliste) associ‚: 
  401.          */
  402.         build_arbodir( &curr_datadir, &tree );
  403.  
  404.         /*
  405.          * Le dossier n'est plus vierge (il y a un elt "IN") 
  406.          */
  407.         /* OLD: set_datastate( curr_datagr, 1 );    /* Plein, Non modifi‚ */
  408.         /*
  409.          * On a fait une modif dans le dossier (auparavant vierge)
  410.          */
  411.         dataDir_setSavState( curr_datadir, SSTATE_MODIFIED, TRUE );
  412.  
  413.         /*
  414.          * Lie ce dossier au datagroup: 
  415.          */
  416.         curr_datagr -> root_dir            = curr_datadir;    /* Dir ppal */
  417.         
  418.     }
  419.  
  420.  
  421.     /* 
  422.      * Param‚trage de la fenˆtre: 
  423.      */
  424.     wi_params_adr -> content_ptr.datadir= curr_datadir;/* Contenu */
  425.                                         /* Ce setting est trŠs important
  426.                                          *    pour la recherche de la fenˆtre
  427.                                          *    par find_datawindow lorsque l'on
  428.                                          *    veut par ex dupliquer son contenu 
  429.                                          */    
  430.     wi_params_adr -> datadir = curr_datadir;    /* Ptr sur datadir */
  431.     wi_params_adr -> draw_ptr.tree     = tree;                /* Pointeur sur arbre d'objets */
  432.     wi_params_adr -> total_w            = tree[0].ob_width + WA_OUTLINE;
  433.     wi_params_adr -> total_h            = tree[0].ob_height + WA_OUTLINE;
  434.     wi_params_adr -> h_step                = G_arbocell_w;    /* Saut par emplacement */
  435.     wi_params_adr -> v_step             = G_arbocell_h;    /* Saut par emplacement */
  436.  
  437.     /*
  438.      * Centrage de la fenˆtre ouverte sur le lien "IN":
  439.      */
  440.     if( find_inlinkXY( curr_datadir, &n_posX, &n_posY ) == SUCCESS0 )
  441.     {    /*
  442.          * Si on a trouv‚ le Lien IN:
  443.          *
  444.          * Centrage en X et haut (mais place pour bordure) de fenˆtre en Y:
  445.          */
  446.         int    n_Xoffset = n_posX * G_arbocell_w + G_arbocell_w/2 - (wi_params_adr -> seen_w)/2 + AICON_OFFX;
  447.         int    n_Yoffset = n_posY * G_arbocell_h;
  448.         
  449.         if( n_Xoffset < 0 )
  450.         {    /* 
  451.              * Si on d‚passe le bord gauche 
  452.              */
  453.             n_Xoffset = 0;
  454.         }
  455.         else if( n_Xoffset + wi_params_adr -> seen_w > wi_params_adr -> total_w )
  456.         {    /* 
  457.              * Si on d‚passe le bord droit 
  458.              */
  459.             n_Xoffset = (int) (wi_params_adr -> total_w - wi_params_adr -> seen_w);
  460.         }
  461.  
  462.         if( n_Yoffset < 0 )
  463.         {    /* 
  464.              * Si on d‚passe le bord sup‚rieur
  465.              */
  466.             n_Yoffset = 0;
  467.         }
  468.         else if( n_Yoffset + wi_params_adr -> seen_h > wi_params_adr -> total_h )
  469.         {    /* 
  470.              * Si on d‚passe le bord inf‚rieur:
  471.              */
  472.             n_Yoffset = (int) (wi_params_adr -> total_h - wi_params_adr -> seen_h);
  473.         }
  474.  
  475.         wi_params_adr -> seen_x    = n_Xoffset;        /* Offset X */
  476.         wi_params_adr -> seen_y    = n_Yoffset;        /* Offset Y */
  477.     }
  478.  
  479.     /* 
  480.      * Options menu: 
  481.      */
  482.     wi_params_adr -> menu_options.newlink = TRUE_1;    /* On peut cr‚er des nouveaux liens */
  483.     wi_params_adr -> menu_options.newpage = TRUE_1;    /* On peut cr‚er des nouvelles pages */
  484.  
  485.     /* 
  486.      * 1 fenˆtre semblable de plus: 
  487.      */
  488.     curr_datadir -> nb_dirs ++;
  489.     /* printf( "Ouverture: nb_dirs=%d\n", curr_datadir -> nb_dirs ); */
  490.  
  491. }
  492.  
  493.  
  494. /*
  495.  * build_arbodir(-)
  496.  *
  497.  * Purpose:
  498.  * --------
  499.  * Cr‚ation du contenu d'un dossier dans l'arborescence
  500.  *
  501.  * Suggest:
  502.  * ------
  503.  * passer les trucs trŠs sp‚cifiques ds DIRSPEC
  504.  *
  505.  * History:
  506.  * --------
  507.  * 1993: fplanque: Created
  508.  * 15.07.94: fplanque: appelle maintenant create_EmptyDataDir()
  509.  * 21.09.94: ne considŠre plus qu'il y a un dossier ouvert par d‚faut!
  510.  * 14.05.95: Corrig‚ bug de cr‚ation des Liens-In
  511.  */
  512. void    build_arbodir( 
  513.             DATADIR * * curr_datadir, 
  514.             OBJECT  * * tree )
  515. {
  516.     /*
  517.      * Variables: 
  518.      */
  519.     ICONBLK        *iblk_array;    /* Tableau d'iconblocks */
  520.     size_t        map_size = ( ARBOPAGES_W * ARBOPAGES_H + 2 )* sizeof( unsigned );
  521.                                             /* +2 pour [largeur] et [hauteur] */
  522.     unsigned        *arbo_map;        /* Tableau repr‚sentatif */
  523.  
  524.     DIRSPEC        *dir_spec;        /* Sp‚cifications compl‚mentaires */
  525.  
  526.  
  527.     /* 
  528.      * Cr‚e une zone pour et avec le nouvel arbre d'objets: 
  529.      */
  530.     *tree = (OBJECT *) MALLOC( sizeof( OBJECT ) * (DEF_NBOBJ_TREE+1) ); /* +1 pour la boŒte pŠre */
  531.     memcpy( *tree, M_arbotree, 2*sizeof( OBJECT ) );    /* Copie pŠre + "IN" */
  532.  
  533.     /* 
  534.      * Cr‚e une zone pour les ICONBLKs: 
  535.      */
  536.     iblk_array = (ICONBLK *) MALLOC( sizeof( ICONBLK ) * DEF_NBIBL_TREE );
  537.  
  538.     /* 
  539.      * Cr‚e un tableau repr‚sentant l'arbre: 
  540.      */
  541.     arbo_map = ( unsigned * ) MALLOC( map_size );
  542.     memset( arbo_map, 0, map_size );        /* Initialise tout … z‚ro : cases vides */
  543.     arbo_map[ 0 ]= ARBOPAGES_W;                /* Largeur */
  544.     arbo_map[ 1 ]= ARBOPAGES_H;                /* Hauteur */        
  545.     arbo_map[ 2 + ARBOIN_POSY*ARBOPAGES_W + ARBOIN_POSX ]= IDELT_IN;                     /* Signale l'‚l‚ment "IN" avec une sortie South */
  546.  
  547.     /* 
  548.      * Cr‚e une zone d'infos DATADIR: 
  549.      */
  550.     *curr_datadir = create_EmptyDataDir( find_datagroup_byType( DTYP_ARBO), NULL );
  551.  
  552.     (*curr_datadir) -> iconblks     = iblk_array;
  553.  
  554.     /* 
  555.      * Fixe paramŠtres sp‚ciaux aux DATADIRs ARBO
  556.      */
  557.     dir_spec = (DIRSPEC *) MALLOC ( sizeof( DIRSPEC ) );
  558.     /*
  559.      * BUG: different types:
  560.      */
  561.     dir_spec -> liens_in     = dup_KeyWordList( M_in_arbolinks );
  562.     dir_spec -> max_objs        = DEF_NBOBJ_TREE;
  563.     dir_spec -> nb_objs        = 1;    /* Pour l'instant: 1 elt: "IN" */
  564.     dir_spec -> max_iblks    = DEF_NBIBL_TREE;
  565.     dir_spec -> nb_iblks        = 0;
  566.     dir_spec -> dir_map         = arbo_map;
  567.     (*curr_datadir) -> dir_spec = dir_spec;    /* Sp‚cifications compl‚mentaires */
  568.  
  569. }
  570.  
  571.  
  572. /*
  573.  * efface_arbodir(-)
  574.  *
  575.  * Purpose:
  576.  * --------
  577.  * Efface un dossier de l'arborescence
  578.  *
  579.  * History:
  580.  * --------
  581.  * 1993: fplanque: Created
  582.  */
  583. void    efface_arbodir( DATADIR *datadir )
  584. {
  585.     /*
  586.      * Adresse dir_spec? 
  587.      */
  588.     DIRSPEC    *    dir_spec = datadir -> dir_spec;
  589.  
  590.     /*
  591.      * Petit contr“le: il ne doit plus y avoir de pages ds le datadir: 
  592.      */
  593.     if( datadir -> data_start != NULL )
  594.     {
  595.         signale("On a effac‚ un DIR non vide!!!");
  596.     }
  597.     
  598.     /*
  599.      * Effacement des SPECS 
  600.      * Efface liens-in du dossier: 
  601.      */
  602.     free_KeyWordList( dir_spec -> liens_in );
  603.     /*
  604.      * Effacement du dir-map: 
  605.      */
  606.     FREE( dir_spec -> dir_map );
  607.     /*
  608.      * Efface specs: 
  609.      */
  610.     FREE( dir_spec );    
  611.     datadir -> dir_spec = NULL;
  612.  
  613.     /*
  614.      * Effacement du dossier lui-mˆme: 
  615.      */
  616.     DataDir_Destruct( datadir );
  617. }
  618.     
  619.     
  620. /*
  621.  * build_arbotree(-)
  622.  *
  623.  * Purpose:
  624.  * --------
  625.  * Cr‚ation de l'arbre d'objets repr‚sentant un dossier dans l'arbo
  626.  *
  627.  * History:
  628.  * --------
  629.  * 1993: fplanque: Created
  630.  * 21.09.94: ne touche pas au nb de dirs ouverts simultan‚ment
  631.  */
  632. void    build_arbotree( 
  633.             DATADIR    *    curr_datadir, 
  634.             OBJECT     **    tree )
  635. {
  636.     DIRSPEC    *    pDirSpec = curr_datadir -> dir_spec;
  637.     ICONBLK    *    iblk_array;    /* Tableau d'iconblocks */
  638.     unsigned    *    arbo_map    = pDirSpec -> dir_map;    /* Tableau repr‚sentatif */
  639.     unsigned        map_width    = arbo_map[ 0 ];            /* Largeur tableau */
  640.     unsigned        map_height    = arbo_map[ 1 ];            /* Hauteur tableau */
  641.     unsigned        map_x, map_y;
  642.     unsigned        object_id;            /* ID de l'objet en cours de cr‚ation */
  643.     unsigned    *    map_ptr;            /* Pointeur sur une case */
  644.     /*
  645.      * Cr‚ation des objets: 
  646.      */
  647.     unsigned        nb_objs = 1;        /* Nombre d'objets, par d‚faut: 1: "IN" */
  648.     unsigned        nb_iblks = 0;        /* Nombre d'IBLKS */
  649.     int            offset_x, offset_y;    /* Position des objets quel'on place dans le formulaire */
  650.     int            srce_obj_no;        /* No de l'objet modŠme */
  651.     OBJECT    *    srce_object;        /* ModŠle … recopier */
  652.     OBJECT    *    new_object;        /* Nouvel objet cr‚‚ */
  653.     ICONBLK    *    new_iblk;            /* Nouveau IBLK */
  654.  
  655.     /*
  656.      * Calcule le nombre d'objets qu'on va r‚server: 
  657.      */ 
  658.     pDirSpec -> max_objs = pDirSpec -> nb_objs + DEF_NBOBJ_TREE; /* Nbre d‚j… existant + MARGE */
  659.     /* printf("maxobjs=%d \n", curr_datadir -> max_objs ); */
  660.     /*
  661.      * Cr‚e une zone pour et avec le nouvel arbre d'objets: 
  662.      */
  663.     *tree = (OBJECT *) MALLOC( sizeof( OBJECT ) * (pDirSpec -> max_objs +1) ); /* +1 pour la boŒte pŠre */
  664.     memcpy( *tree, M_arbotree, 2*sizeof( OBJECT ) );    /* Copie pŠre + "IN" */
  665.     /*
  666.      * Adapte la taille du formulaire: 
  667.      */
  668.     tree[ ROOT ] -> ob_width = map_width * G_arbocell_w +WA_BORDER;
  669.     tree[ ROOT ] -> ob_height = map_height * G_arbocell_h +WA_BORDER;
  670.  
  671.     /*
  672.      * Calcule le nombre d'ICONBLOCKS qu'on va r‚server: 
  673.      */ 
  674.     pDirSpec -> max_iblks = pDirSpec -> nb_iblks + DEF_NBIBL_TREE; /* Nbre d‚j… existant + MARGE */
  675.     /* printf("maxiblk=%d \n", pDirSpec -> max_iblks ); */
  676.  
  677.     /*
  678.      * Cr‚e une zone pour les ICONBLKs: 
  679.      */
  680.     iblk_array = (ICONBLK *) MALLOC( sizeof( ICONBLK ) * pDirSpec -> max_iblks );
  681.     /* printf("IBLKARRAY=%lu\n",iblk_array); */
  682.     /*
  683.      * Sauve l'adr de cette nlle zone 
  684.      */    
  685.     curr_datadir -> iconblks     = iblk_array;
  686.     
  687.  
  688.     /*
  689.      * Parcourt le tableau: 
  690.      */
  691.     map_ptr = &(arbo_map[2]);        /* Pointe sur 1Šre case */
  692.     offset_y = AICON_OFFY;            /* Offset Y des objets dans l'arbre */
  693.     for(    map_y = 0;
  694.             map_y < map_height;
  695.             map_y++, offset_y += G_arbocell_h )
  696.     {
  697.         offset_x = AICON_OFFX;        /* Offset X des objets dans l'arbre */
  698.         for(    map_x = 0;
  699.                 map_x < map_width;
  700.                 map_x++, offset_x += G_arbocell_w )
  701.         {
  702.             object_id = *(map_ptr++);    /* ID de l'objet se trouvant … cette position */                    
  703.             if ( object_id != 0 )
  704.             {    /* Si la case n'est pas vide: */
  705.  
  706.                 if ( object_id & CT_ARBO )
  707.                 {    /* S'il s'agit d'une page ARBO: */
  708.  
  709.                     /*
  710.                      * On recherche la page qui se trouve 
  711.                      *    aux coordonn‚es en cours d'investigation: 
  712.                      */
  713.                     DATAPAGE    *datapage = find_arbo_by_xy ( curr_datadir, map_x, map_y );
  714.  
  715.                     if( datapage != NULL )    /* Normalement NULL ne devrait jamais arriver */
  716.                     {    /*
  717.                          * Si on a trouv‚ la page qui se trouve aux coordonn‚es courantes 
  718.                          */
  719.                         PAGEARBO    *pagearbo = datapage -> data.pagearbo;
  720.  
  721.                         /* printf("Trouv‚ page: %lu\n", datapage ); */
  722.  
  723.                         /*
  724.                          * D‚duit adr de l'objet source: 
  725.                          */
  726.                         srce_object = &M_newpagearbo_adr[ (pagearbo -> fnct_spec) -> icon_no ];
  727.  
  728.                         /*
  729.                          * Ajoute l'ic“ne PAGE-ARBO dans l'arbre: 
  730.                          */
  731.                         new_object = add_arbo_elt( *tree, srce_object, &nb_objs );
  732.  
  733.                         /*
  734.                          * Duplique IBLK 
  735.                          */
  736.                         new_iblk = &( iblk_array[ nb_iblks++ ] );    /* Adresse copie (Un IBLK de plus) */
  737.                         memcpy( new_iblk, srce_object -> ob_spec.iconblk, sizeof( ICONBLK ) ); /* Copie */
  738.                         /*
  739.                          * Lie IBLK … l'objet: 
  740.                          */
  741.                         new_object -> ob_spec.iconblk = new_iblk;
  742.                         /*
  743.                          * Modifie le nom de la page dans l'ICONBLK: 
  744.                          */
  745.                         new_iblk -> ib_ptext = datapage -> nom; /* Fixe ptr sur nom */
  746.  
  747.                     }
  748.                     else
  749.                     {
  750.                         signale("Page pos‚e dans le MAP mais introuvable dans LISTE");
  751.                     }
  752.                 }
  753.                 else
  754.                 {    /* S'il s'agit d'un LIEN */
  755.                     if ( object_id == IDELT_IN )
  756.                     {    /* S'il s'agit du point d'entr‚e: */
  757.                         /* Cet elt fait d‚j… partie de l'arbre */
  758.                         new_object = &(*tree)[ 1 ];        /* D‚termine son adresse */
  759.                     }
  760.                     else
  761.                     {    /* S'il s'agit d'un lien standard: */
  762.                     /* Recherche no de l'image du lien demand‚ */
  763.                         srce_obj_no = 0;
  764.                         while( M_link_id[ srce_obj_no ] != object_id && srce_obj_no < NB_LINKTYPES )
  765.                         {
  766.                             srce_obj_no ++;        /* Objet suivant */
  767.                         }
  768.                     /* Transforme en no d'objet dans l'arbre M_newlink_adr: */
  769.                         srce_obj_no += LKFETS;        /* Add no du 1er lien du formulaire */
  770.                     /* D‚duit adr de l'objet source: */
  771.                         srce_object = &M_newlink_adr[ srce_obj_no ];
  772.  
  773.                     /* Ajoute l'ic“ne LIEN dans l'arbre: */
  774.                         new_object = add_arbo_elt( *tree, srce_object, &nb_objs );
  775.                     }
  776.                 }
  777.  
  778.                 /*
  779.                  * Fixe les coordonn‚es du nouvel objet: 
  780.                  */
  781.                 new_object -> ob_x = offset_x;
  782.                 new_object -> ob_y = offset_y;
  783.  
  784.             }
  785.         }
  786.     }
  787. }
  788.  
  789.  
  790.  
  791. /*
  792.  * afnct_spec(-)
  793.  *
  794.  * Purpose:
  795.  * --------
  796.  * Trouve adr des sp‚cification associ‚es … une fonction arbo
  797.  *
  798.  * History:
  799.  * --------
  800.  * 1993: fplanque: Created
  801.  * 10.11.94: more debug info
  802.  */
  803. AFNCTSPEC    *afnct_spec( int fnct )
  804. {
  805.     AFNCTSPEC *afnctspec = M_fnctarbo;        /* Adresse du tableau des fonctions arbo */
  806.     int    i;
  807.  
  808.     for( i=0; i<NB_FNCTARBO; i++ )
  809.     {
  810.         if ( afnctspec[ i ] .fnct_no == fnct )
  811.             break;
  812.     }
  813.     
  814.     if( i == NB_FNCTARBO )
  815.     {    /*
  816.          * Si pas trouv‚ 
  817.          */
  818.         ping();
  819.         TRACE1( "Fonction ARBO %d inconnue", fnct );
  820.         return    afnctspec;        /* Renvoie adr 1ere fonction */
  821.     }
  822.     else
  823.     {
  824.         return    &afnctspec[ i ];
  825.     }
  826. }
  827.  
  828.  
  829. /*
  830.  * find_arbo_by_xy(-)
  831.  *
  832.  * Purpose:
  833.  * --------
  834.  * Trouve la page arbo se trouvant aux coordonn‚es X,Y
  835.  *
  836.  * Algorythm:
  837.  * ----------  
  838.  * Parcourt toutes les pages du DIR et v‚rifie leurs coordonn‚es
  839.  *
  840.  * History:
  841.  * --------
  842.  * 1993: fplanque: Created
  843.  */
  844. DATAPAGE    *    find_arbo_by_xy( 
  845.                     DATADIR *    datadir, 
  846.                     int             pos_x, 
  847.                     int             pos_y )
  848. {
  849.     DATAPAGE    *datapage = datadir -> data_start;    /* 1Šre page */
  850.     PAGEARBO    *pagearbo;
  851.  
  852.     while( datapage != NULL )
  853.     {    /*
  854.          * On se place sur les infos pagearbo: 
  855.          */
  856.         pagearbo = datapage -> data.pagearbo;
  857.  
  858.         /*
  859.          *    Teste si on est sur la page cherch‚e 
  860.          */
  861.         if(     pagearbo -> map_pos_y == pos_y
  862.             &&    pagearbo -> map_pos_x == pos_x )
  863.         {
  864.             break;        /* Sort si on a trouv‚ */
  865.         }
  866.     
  867.         /*
  868.          * Passe … la page suivante: 
  869.          */
  870.         datapage = datapage -> next;
  871.     }
  872.  
  873.     if( datapage == NULL )
  874.     {    /*
  875.          * Si la page n'a pas ‚t‚ trouv‚e! 
  876.          */
  877.         signale("Page arbo recherch‚e n'est pas d‚finie");
  878.     }
  879.  
  880.     return    datapage;
  881. }
  882.  
  883.  
  884.  
  885. /*
  886.  * find_inlinkXY(-)
  887.  *
  888.  * Purpose:
  889.  * --------
  890.  * Trouve les coordonn‚es X,Y de l'‚l‚ment Lien IN
  891.  *
  892.  * Algorythm:
  893.  * ----------  
  894.  * Cherche l'‚l‚ment dans le MAP
  895.  *
  896.  * History:
  897.  * --------
  898.  * 17.05.94: fplanque: Created
  899.  */
  900. int    find_inlinkXY(                     /* Out: !=0 si non trouv‚ (erreur) */        
  901.                 DATADIR    * pDataDir,        /* In:  Datadir dans lequel on cherche */
  902.                 int        * pn_posX,        /* Out: Position X en cases */
  903.                 int        * pn_posY )        /* Out: Position Y en cases */
  904. {
  905.     /*
  906.      * Plan du directory:
  907.      */
  908.     DIRSPEC    *    pDirSpec = pDataDir -> dir_spec;
  909.     unsigned    *    Tu_ArboMap = pDirSpec -> dir_map;
  910.     unsigned        u_mapW = Tu_ArboMap[ 0 ];
  911.     unsigned        u_mapH = Tu_ArboMap[ 1 ];
  912.     int            n_i;
  913.  
  914.     /*
  915.      * Parcourt le map:
  916.      */
  917.     for( n_i = 2; n_i < (u_mapW * u_mapH) + 2; n_i ++ )
  918.     {
  919.         if( Tu_ArboMap[ n_i ] == IDELT_IN )
  920.         { /*
  921.             * Si on a trouv‚ l'‚lement LIEN IN:
  922.             */
  923.             *pn_posY = (n_i-2) / u_mapW;
  924.             *pn_posX = (n_i-2) % u_mapW;
  925.             
  926.             return    SUCCESS0;
  927.         }
  928.     }
  929.     
  930.     return    CORRUPT_1;
  931. }
  932.  
  933.  
  934.  
  935. /*
  936.  * add_arbo_elt(-)
  937.  *
  938.  * Purpose:
  939.  * --------
  940.  * Ajoute un nouvel objet dans l'arbo
  941.  *
  942.  * History:
  943.  * --------
  944.  * 1993: fplanque: Created
  945.  * 21.09.94: gestion des flags LASTOB
  946.  */
  947. OBJECT    *add_arbo_elt( 
  948.                 OBJECT    *    tree, 
  949.                 OBJECT     *    srce_object, 
  950.                 unsigned *    nb_objs )
  951. {
  952.     /*
  953.      * Adresse de l'objet nouveau lien: 
  954.      */
  955.     OBJECT    *new_object;
  956.     
  957.     /*
  958.      * Comme on ajoute un objet le dernier objet actuel
  959.      * ne sera bientot plus le dernier:
  960.      */
  961.     tree[ *nb_objs ] .ob_flags &= ~LASTOB;
  962.     
  963.     /*
  964.      * 1 objet de plus: 
  965.      */
  966.     (*nb_objs) ++;
  967.  
  968.     /*
  969.      * Adresse nouvel objet: 
  970.      */
  971.     new_object = &( tree[ *nb_objs ] );    
  972.  
  973.     /*
  974.      * Copie l'objet-lien: 
  975.      */
  976.     memcpy( new_object, srce_object, sizeof( OBJECT ) );
  977.  
  978.     /*
  979.      * Fixe flags: 
  980.      * Nvel objet peut ˆtre s‚lectionn‚
  981.      * Ce le nouveau DERNIER objet de l'arbre!
  982.      */
  983.     (new_object -> ob_flags) |= SELECTABLE | LASTOB;    
  984.     
  985.     /* printf("Flags=%X \n",new_object -> ob_flags); */
  986.  
  987.     /*
  988.      * Lie l'objet: 
  989.      */
  990.     objc_add( tree, 0, *nb_objs );
  991.  
  992.     return    new_object;
  993. }
  994.  
  995.  
  996.  
  997. /*
  998.  * efface_arbotree(-)
  999.  *
  1000.  * Purpose:
  1001.  * --------
  1002.  * Efface un arbre d'objet arbo dans 1 fenˆtre et la zone 
  1003.  * d'ICONBLKS s'il s'agissait de la derniŠre fenˆtre
  1004.  *
  1005.  * History:
  1006.  * --------
  1007.  * 1993: fplanque: Created
  1008.  * 21.09.94: Correction bug sur d‚cr‚mentation nb_dirs
  1009.  */
  1010. void    efface_arbotree( WIPARAMS *wi_params_adr )
  1011. {
  1012.     /*
  1013.      * R‚pertoire affich‚ dans la fenˆtre: 
  1014.      */
  1015.     DATADIR    *datadir = wi_params_adr -> datadir;
  1016.  
  1017.     /*
  1018.      * Une fenˆtre de moins dans DATDIR ET DATAGROUP... 
  1019.      */
  1020.     (datadir -> nb_dirs)--;
  1021.     /*
  1022.      * Teste s'il reste des fenˆtres semblables 
  1023.      */
  1024.     if ( datadir -> nb_dirs == 0)
  1025.     {    /*
  1026.          * Si on vient de fermer la derniŠre fenˆtre: 
  1027.          */
  1028.         if ( datadir -> iconblks != NULL )
  1029.         {    /*
  1030.              * S'il y avait des ic“nes et donc une zone d'ICONBLKs
  1031.              *    ds la derniŠre fenˆtre: 
  1032.              */
  1033.             FREE( datadir -> iconblks );    /* Efface tableau d'ICONBLK: */
  1034.             datadir -> iconblks = NULL;    /* Signale qu'on a ‚ffac‚ les ICONBLK
  1035.                                                      *    Ceci est important afin de d‚terminer,
  1036.                                                      *    lors de la r‚-ouverture du dossier,
  1037.                                                      *    s'il faut les re-cr‚er ou pas, en l'occurence: OUI !
  1038.                                                      */
  1039.         }
  1040.     }
  1041.  
  1042.     /*
  1043.      * Efface arbre d'ic“nes de la m‚moire 
  1044.      */
  1045.     FREE( wi_params_adr -> draw_ptr.tree );
  1046. }
  1047.  
  1048.                 
  1049.                 
  1050. /*
  1051.  * arbo_infoline(-)
  1052.  *
  1053.  * Purpose:
  1054.  * --------
  1055.  * Modifie la ligne d'informations sur l'arbo
  1056.  *
  1057.  * History:
  1058.  * --------
  1059.  * 1993: fplanque: Created
  1060.  */
  1061. char    *    arbo_infoline( 
  1062.                 WIPARAMS *wi_params_adr )
  1063. {
  1064.     DATADIR    *    datadir = wi_params_adr -> datadir;
  1065.     DIRSPEC    *    pDirSpec = datadir -> dir_spec;
  1066.     int            nb_elts    = datadir -> nb_elts;
  1067.     int            nb_links = pDirSpec -> nb_objs - nb_elts;
  1068.  
  1069.     /* Cr‚ation de la ligne d'infos: */
  1070.     G_tmp_buffer[ 0 ] = ' ';
  1071.  
  1072.     itoa( nb_elts, &G_tmp_buffer[ 1 ], 10 );    /* Nombre d'‚l‚ments */
  1073.     if ( nb_elts <= 1 )
  1074.         strcat( G_tmp_buffer, " page, " );
  1075.     else
  1076.         strcat( G_tmp_buffer, " pages, " );
  1077.  
  1078.     itoa( nb_links, &G_tmp_buffer[ strlen( G_tmp_buffer ) ], 10 );    /* Nombre de liens */
  1079.     if ( nb_links <= 1 )
  1080.         strcat( G_tmp_buffer, " lien." );
  1081.     else
  1082.         strcat( G_tmp_buffer, " liens." );
  1083.  
  1084.     return    STRDUP( G_tmp_buffer );
  1085. }
  1086.  
  1087.  
  1088.  
  1089. /*
  1090.  * arbo_infoline_selection(-)
  1091.  *
  1092.  * Purpose:
  1093.  * --------
  1094.  * Modifie la ligne d'informations sur l'arbo 
  1095.  * lorsqu'on a s‚lectionn‚ une icone
  1096.  *
  1097.  * History:
  1098.  * --------
  1099.  * 1993: fplanque: Created
  1100.  */
  1101. char    * arbo_infoline_selection( 
  1102.                 WIPARAMS * wi_params_adr )
  1103. {
  1104.     DATADIR        *datadir            = wi_params_adr -> datadir;
  1105.     int            selected_icon    = wi_params_adr -> selected_icon;
  1106.     OBJECT        *selected_obj    = &(wi_params_adr -> draw_ptr.tree)[selected_icon];
  1107.  
  1108.     /*
  1109.      * Controle type: 
  1110.      */
  1111.     if ( selected_obj -> ob_type == G_IMAGE )
  1112.     {    /*
  1113.          * S'il s'agit d'un lien (G_IMAGE): 
  1114.          */
  1115.         strcpy( G_tmp_buffer, " 1 lien s‚lectionn‚." );
  1116.     }
  1117.     else
  1118.     {    /*
  1119.          * S'il s'agit d'un page (G_ICON): 
  1120.          */
  1121.         char            *dataname        = (selected_obj -> ob_spec.iconblk) -> ib_ptext;
  1122.         DATAPAGE        *datapage         = page_adr_byname( datadir, dataname ); 
  1123.         char            *comment            = datapage -> comment;
  1124.  
  1125.         /*
  1126.          * Cr‚ation de la ligne d'infos: 
  1127.          */
  1128.         strcpy( G_tmp_buffer, " S‚lection: " );
  1129.         strcat( G_tmp_buffer, dataname );        /* Ajoute nom de la page */
  1130.         if ( comment != NULL )
  1131.         {
  1132.             strcat( G_tmp_buffer, " = " );
  1133.             strcat( G_tmp_buffer, comment );        /* Ajoute commentaire */
  1134.         }
  1135.     }
  1136.     
  1137.     return    STRDUP( G_tmp_buffer );
  1138. }
  1139.  
  1140.  
  1141.  
  1142. /*
  1143.  * arbotree_optimal(-)
  1144.  *
  1145.  * Purpose:
  1146.  * --------
  1147.  * Calcul des coordonn‚es optimales pour le full-screen window
  1148.  *
  1149.  * History:
  1150.  * --------
  1151.  * 1993: fplanque: Created
  1152.  * 16.03.95: corrig‚ petit bug d'accŠs … DirSpec
  1153.  */
  1154. void    arbotree_optimal( 
  1155.             int            wi_ckind, 
  1156.             DATADIR    *    datadir, 
  1157.             int         *    border_x, 
  1158.             int        *    border_y, 
  1159.             int        *    border_w, 
  1160.             int        *    border_h)
  1161. {
  1162.     int            map_width, map_height;
  1163.     int            form_w, form_h;
  1164.  
  1165.     /*
  1166.      * Trouve taille du map:
  1167.      */
  1168.     if( datadir == NULL )
  1169.     {    /*
  1170.          * Taille par d‚faut: 
  1171.          */
  1172.         map_width = ARBOPAGES_W;
  1173.         map_height = ARBOPAGES_H;
  1174.     }
  1175.     else
  1176.     {    /*
  1177.          * Taille actuelle: 
  1178.          */
  1179.         DIRSPEC    *    pDirSpec = datadir -> dir_spec;
  1180.         map_width = pDirSpec -> dir_map[ 0 ];
  1181.         map_height = pDirSpec -> dir_map[ 1 ];
  1182.     }
  1183.  
  1184.     /*
  1185.      * Taille du formulaire aes 
  1186.      */
  1187.     form_w = map_width * G_arbocell_w +WA_BORDER +WA_OUTLINE;
  1188.     form_h = map_height * G_arbocell_h +WA_BORDER +WA_OUTLINE;
  1189.  
  1190.     /*
  1191.      * Calcule les coordonn‚es totales de la fenˆtre: 
  1192.      */
  1193.     wind_calc( WC_BORDER, wi_ckind, 50, 50, form_w, form_h,
  1194.                     border_x, border_y, border_w, border_h );
  1195.  
  1196.     /*
  1197.      * Contr“le taille + centrage: 
  1198.      */
  1199.     if ( *border_w > G_w_maxi )
  1200.         *border_w = G_w_maxi;
  1201.     *border_x = G_x_mini + (G_w_maxi - *border_w) /2;
  1202.  
  1203.     if ( *border_h > G_h_maxi )
  1204.         *border_h = G_h_maxi;
  1205.     *border_y = G_y_mini + (G_h_maxi - *border_h) /2;
  1206. }
  1207.  
  1208.  
  1209.  
  1210.                
  1211.                
  1212. /*
  1213.  * select_newarbo(-)
  1214.  *
  1215.  * Purpose:
  1216.  * --------
  1217.  * S‚lection d'un nouvel element … placer dans une arbo
  1218.  *
  1219.  * History:
  1220.  * --------
  1221.  * 22.01.95: fplanque: extracted from new_arbo()
  1222.  * 23.01.95: empeche double click
  1223.  */
  1224. OBJECT *    select_newarbo(
  1225.             int                 type, 
  1226.             const GRECT *    start_box,
  1227.             int            * ob_x,        /* Out: Coordonn‚es de l'objet s‚lectionn‚ */
  1228.             int            * ob_y,
  1229.             int            * ob_w,
  1230.             int            * ob_h,
  1231.             UINT            * object_id )    /* Out: 'forme' de l'objet */
  1232. {
  1233.     GRECT        form_box;                    /* Dimensions du formulaire */
  1234.     OBJECT    *form_adr;                    /* Adresse du formulaire */
  1235.     int        annuler;                        /* No du bouton "Annuler" */
  1236.     int        exit_obj;
  1237.     int        edit_obj = 0;                /* Bidon */
  1238.  
  1239.     OBJECT    *    newlink_obj;
  1240.     
  1241.     /*
  1242.      * Teste si on va ajouter un lien ou une page: 
  1243.      */
  1244.     switch( type )
  1245.     {
  1246.         case    0:
  1247.             form_adr = M_newlink_adr;
  1248.             annuler    = NEWLKANN;
  1249.             break;
  1250.             
  1251.         case    1:
  1252.             form_adr = M_newpagearbo_adr;
  1253.             annuler    = NEWPAGAN;
  1254.             break;
  1255.             
  1256.         default:
  1257.             ping();
  1258.     }
  1259.  
  1260.     /*
  1261.      * Affiche/gŠre formulaire: 
  1262.      */
  1263.     open_panel( form_adr, start_box, &form_box, TRUE_1 );
  1264.  
  1265.     do
  1266.     {
  1267.         exit_obj = ext_form_do( form_adr, &edit_obj );    /* Gestion de la boŒte */
  1268.  
  1269.     } while( exit_obj & 0x8000 );        /* ne sort pas Si on a double cliqu‚ */
  1270.  
  1271.     if( exit_obj == annuler )
  1272.     {    /*
  1273.          * Si on a annul‚: 
  1274.          */
  1275.         abort_pannel( form_adr, exit_obj, start_box, &form_box );
  1276.  
  1277.         return NULL;
  1278.     }
  1279.  
  1280.  
  1281.     /*
  1282.      * Adresse de l'objet - nouveau lien: 
  1283.      */
  1284.     newlink_obj = &(form_adr[ exit_obj ]);
  1285.  
  1286.     /*
  1287.      * Ferme formulaire 
  1288.      */            
  1289.     close_pannel( form_adr, exit_obj, &form_box );
  1290.  
  1291.     /*
  1292.      * Coord de d‚part du drag: 
  1293.      */
  1294.     objc_offset( form_adr, exit_obj, ob_x, ob_y );
  1295.     *ob_w = newlink_obj -> ob_width;
  1296.     *ob_h = newlink_obj -> ob_height;
  1297.  
  1298.  
  1299.     /*
  1300.      * Trouve la forme de l'ic“ne: 
  1301.      */
  1302.     switch( type )
  1303.     {
  1304.         case    0:                /* Lien */
  1305.             *object_id = M_link_id[ exit_obj - LKFETS ];
  1306.             break;
  1307.             
  1308.         case    1:                /* Page arbo */
  1309.             *object_id = IDPAGE_STD;
  1310.             break;
  1311.             
  1312.         default:
  1313.             signale( "Lien ou ic“ne??" );
  1314.     }
  1315.     /* printf("ID:%X\n",object_id); */
  1316.  
  1317.  
  1318.     return    newlink_obj;
  1319.  
  1320. }
  1321.  
  1322.  
  1323.  
  1324.  
  1325.     
  1326. /*
  1327.  * add_newarbo(-)
  1328.  *
  1329.  * Purpose:
  1330.  * --------
  1331.  * S‚lection d'un nouvel element … placer dans une arbo
  1332.  *
  1333.  * History:
  1334.  * --------
  1335.  * 22.01.95: fplanque: extracted from new_arbo()
  1336.  */
  1337. BOOL    add_newarbo(                            /* Out: TRUE_1 si ok */
  1338.             unsigned            object_id,        /* In: forme de l'objet */
  1339.             OBJECT        *    newlink_obj,    /* In: ModŠle d'objet … ajouter */
  1340.             const GRECT *    start_box,
  1341.             int                drop_x,            /* In: Coordonn‚es de placement */
  1342.             int                drop_y )
  1343. {
  1344.     DATADIR    *    curr_datadir = G_wi_list_adr -> datadir;   /* Dossier concern‚ */
  1345.     DIRSPEC    *    pDirSpec = curr_datadir -> dir_spec;
  1346.     unsigned    *    nb_objs = &(pDirSpec -> nb_objs);
  1347.     unsigned    *    nb_iblks = &(pDirSpec -> nb_iblks);
  1348.     int            pos_x = (G_wi_list_adr -> draw_ptr.tree) -> ob_x + drop_x * G_arbocell_w +AICON_OFFX;
  1349.     int            pos_y = (G_wi_list_adr -> draw_ptr.tree) -> ob_y + drop_y * G_arbocell_h +AICON_OFFY;
  1350.     OBJECT    *    tree = G_wi_list_adr -> draw_ptr.tree;
  1351.     OBJECT    *    newelt_cpy;    /* Adresse de la copie du lien/page int‚gr‚e … l'arbre d'objets */
  1352.     ICONBLK    *    iblk_array = curr_datadir -> iconblks;
  1353.     ICONBLK    *    newiblk_cpy;    /* Adresse de la copie de l'iconblk int‚gr‚e … l'arbre d'objets */
  1354.     int            link_x, link_y;
  1355.     int            work_x = G_wi_list_adr -> work_x,
  1356.                     work_y = G_wi_list_adr -> work_y;
  1357.     GRECT            dest_box;        /* Coord nlle ic“ne ds denˆtre */
  1358.     /*
  1359.      * Adresse du map: 
  1360.      */
  1361.     unsigned    *    arbo_map = pDirSpec -> dir_map;    /* Avant, on prenait le datadir, ds le content */
  1362.  
  1363.     /*
  1364.      * Effet graphique d'ouverture sur cet emplacement: 
  1365.      */
  1366.     graf_growbox( start_box -> g_x, start_box -> g_y,
  1367.                         start_box -> g_w -8, start_box -> g_h,
  1368.                         pos_x, pos_y, G_arbocell_w, G_arbocell_h );
  1369.     /*
  1370.      * Ce -8 pourrait paraitre bizarre, en effet! 
  1371.      * Il evite la d‚g‚n‚rescence de l'effet graphique si la 
  1372.      * source est bcp plus large que la destination! 
  1373.      */
  1374.  
  1375.     /*
  1376.      * Contr“le si on a la place de l'ajouter: 
  1377.      */
  1378.     if( *nb_objs >= pDirSpec -> max_objs )
  1379.     {    /*
  1380.           * Pas la place de l'ajouter 
  1381.           */
  1382.         signale("Object room overflow");    /* PROVISOIRE */
  1383.         return    FALSE0;
  1384.     }
  1385.  
  1386.     if( (object_id & CT_ARBO)  &&  (*nb_iblks) >= pDirSpec -> max_iblks )
  1387.     {    /*
  1388.          * Pas la place d'ajouter ICONBLK pour icone page arbo
  1389.          */
  1390.         signale("ICONBLK room overflow");    /* PROVISOIRE */
  1391.         return    FALSE0;
  1392.     }
  1393.     
  1394.     /*
  1395.      * Ajoute/Copie l'objet-lien/page-arbo … l'arbre
  1396.      * (Un objet de plus): 
  1397.      */
  1398.     newelt_cpy = add_arbo_elt( tree, newlink_obj, nb_objs );
  1399.                 
  1400.     /*
  1401.      * Si page, duplication de l'iconblk 
  1402.      */
  1403.     if( object_id & CT_ARBO )
  1404.     {    /*
  1405.           * Si page: 
  1406.          * -------- 
  1407.          * Duplique IBLK 
  1408.          */
  1409.         newiblk_cpy = &( iblk_array[ *nb_iblks ] );    /* Adresse copie */
  1410.         memcpy( newiblk_cpy,
  1411.              newlink_obj -> ob_spec.iconblk,
  1412.              sizeof( ICONBLK ) ); /* Copie */
  1413.         (*nb_iblks)++;        /* Un IBLK de plus */
  1414.         
  1415.         /*
  1416.          * Lie IBLK … l'objet: 
  1417.          */
  1418.         newelt_cpy -> ob_spec.iconblk = newiblk_cpy;
  1419.     }
  1420.                 
  1421.     /*
  1422.      * Fixe coordonn‚es: 
  1423.      */
  1424.     newelt_cpy -> ob_x = drop_x * G_arbocell_w + AICON_OFFX;
  1425.     newelt_cpy -> ob_y = drop_y * G_arbocell_h + AICON_OFFY;
  1426.     objc_offset( tree, *nb_objs, &link_x, &link_y );
  1427.  
  1428.     /* ---------------------------- */
  1429.     /* Redraw de la zone concern‚e: */
  1430.     /* ---------------------------- */
  1431.     dest_box .g_x = max( work_x, link_x );
  1432.     dest_box .g_y = max( work_y, link_y );
  1433.     dest_box .g_w = min( work_x + G_wi_list_adr -> seen_w, link_x + G_arbocell_w) - dest_box .g_x;
  1434.     dest_box .g_h = min( work_y + G_wi_list_adr -> seen_h, link_y + G_arbocell_h) - dest_box .g_y;
  1435.     /* printf("Dessin zone:%d %d %d %d\n",dest_box .g_x,dest_box .g_y,dest_box .g_w,dest_box .g_h); */
  1436.  
  1437.     if( object_id & CT_ARBO )
  1438.     {    /*
  1439.          * S'il s'agit d'une ic“ne page: 
  1440.          */
  1441.         (newelt_cpy -> ob_state) |= SELECTED;    /* S‚lectionne */
  1442.     }
  1443.     objc_draw( tree, 0, 2, dest_box .g_x, dest_box .g_y, dest_box .g_w, dest_box .g_h);
  1444.  
  1445.     /* 
  1446.      * Solution alternative:
  1447.      *    … utiliser le jour ou on pourra placer l'ic“ne dans une fenˆtre
  1448.      * qui n'est pas au TOP ! :
  1449.      *    modif_icon( G_wi_list_adr, 0,*nb_objs, <<<selected>>>, CTRL_OK );
  1450.      */
  1451.  
  1452.     /*
  1453.      * Signale l'objet dans le tableau arbo_map 
  1454.      */
  1455.     arbo_map[ drop_y * arbo_map[0] + drop_x +2 ]        /* +2 pour Larg et Haut en 0 et 1 */
  1456.             = object_id;
  1457.  
  1458.     if( object_id & CT_ARBO )
  1459.     {    /*
  1460.          * Si on vient de placer une page arbo: 
  1461.          */
  1462.  
  1463.         char         *    pMsz_NewName;
  1464.         char         *    pMsz_NewComment;
  1465.         DATAPAGE    *    datapage;
  1466.         
  1467.         /*
  1468.          * ***************
  1469.          * Demande le nom: 
  1470.          * ***************
  1471.          */
  1472.         pMsz_NewName = query_newname( &dest_box, "NOUVELLE PAGE ARBORESCENCE", NULL, NULL, &pMsz_NewComment, CTRL_OK );
  1473.  
  1474.         if( pMsz_NewName == NULL )
  1475.         {    /*
  1476.              * On a annul‚:
  1477.              */
  1478.             arbo_map[ drop_y * arbo_map[0] + drop_x +2 ] = 0;
  1479.             if( object_id & CT_ARBO )
  1480.             {
  1481.                 (*nb_iblks)--;        /* Un IBLK de moins  */
  1482.             }
  1483.             objc_delete( tree, *nb_objs );
  1484.             (*nb_objs)--;
  1485.             tree[ *nb_objs ] .ob_flags |= LASTOB;
  1486.             /*
  1487.              * Redraw de la zone concern‚e: 
  1488.              */
  1489.             objc_draw( tree, 0, 2, dest_box .g_x, dest_box .g_y, dest_box .g_w, dest_box .g_h);
  1490.         }
  1491.         else
  1492.         {    /*
  1493.              * On a confirm‚
  1494.              * Cr‚e la nouvelle page en m‚moire: 
  1495.              */
  1496.             /* printf("Type de la page: %X\n",(newlink_obj -> ob_type)>>8); */
  1497.  
  1498.             datapage = cree_pagearbo( curr_datadir, (newlink_obj -> ob_type)>>8, pMsz_NewName, drop_x, drop_y );
  1499.             FREE( pMsz_NewName );
  1500.  
  1501.             /*
  1502.              * Fixe commentaire:
  1503.              */
  1504.             datapage -> comment = pMsz_NewComment;
  1505.  
  1506.             /*
  1507.              * Modifie ICONBLK: 
  1508.              */
  1509.             newiblk_cpy -> ib_ptext = datapage -> nom; /* Fixe ptr sur nom */
  1510.             /*
  1511.              * Redraw de la zone concern‚e: 
  1512.              */
  1513.             newelt_cpy -> ob_state &= (!SELECTED);    /* D‚s‚lectionne */
  1514.             objc_draw( tree, 0, 2, dest_box .g_x, dest_box .g_y, dest_box .g_w, dest_box .g_h);
  1515.     
  1516.             /*
  1517.              * Signale que le dossier courant a ‚t‚ modifi‚
  1518.              */
  1519.             dataPage_chgSavState( datapage, SSTATE_MODIFIED, TRUE_1, TRUE_1 );
  1520.     
  1521.             /*
  1522.              * AUTOLINK:
  1523.              * Liaison automatique avec le pŠre de la nouvelle page:
  1524.              */
  1525.             link_arbo_to_parent( curr_datadir, drop_x, drop_y );
  1526.         }
  1527.     }
  1528.  
  1529.     return    TRUE_1;
  1530. }
  1531.  
  1532.  
  1533.  
  1534. /*
  1535.  * new_arbo(-)
  1536.  *
  1537.  * Purpose:
  1538.  * --------
  1539.  * Cr‚ation d'un nouveau lien/page arbo
  1540.  *
  1541.  * Algorythm:
  1542.  * ----------  
  1543.  *
  1544.  * History:
  1545.  * --------
  1546.  * 1993: fplanque: Created
  1547.  * 22.11.94: teste fen ouverte avant d'agir
  1548.  * 22.11.94: efface newname obtenu par query_newname()
  1549.  * 17.12.94: fixe flag modified
  1550.  */
  1551. void    new_arbo( 
  1552.             int                 type, 
  1553.             const GRECT *    start_box )
  1554. {
  1555.     OBJECT    *    newlink_obj;
  1556.     unsigned        object_id;
  1557.  
  1558.     /*
  1559.      * Coord objet en position de d‚part: 
  1560.      */
  1561.     int        ob_x, ob_y, ob_w, ob_h;
  1562.     /*
  1563.      * Coordonn‚es de relachement: 
  1564.      */
  1565.     int        drop_x, drop_y;
  1566.     int        valid;                /* Validit‚ du relachement */
  1567.  
  1568.  
  1569.     if( G_wi_list_adr == NULL 
  1570.         || G_wi_list_adr -> type != TYP_TREE )
  1571.     {
  1572.         ping();
  1573.         return;
  1574.     }
  1575.     
  1576.     /*
  1577.      * Simule "construction ‚cran" pour empˆcher 
  1578.      * l'AES de d‚rouler ses menus: 
  1579.      */
  1580.     start_WINDRAW( NULL );
  1581.  
  1582.     /*
  1583.      * S‚lection d'un noyvel objet:
  1584.      */
  1585.     newlink_obj = select_newarbo( type, start_box, &ob_x, &ob_y, &ob_w, &ob_h, &object_id );
  1586.  
  1587.     if( newlink_obj == NULL )
  1588.     {    /*
  1589.           * On a annul‚:
  1590.          * Fin construction ‚cran:
  1591.          */
  1592.         end_WINDRAW();
  1593.     
  1594.         return;
  1595.     }
  1596.     
  1597.  
  1598.     /*
  1599.      * Positionne l'arbre d'objets de la fenetre au top: 
  1600.      */
  1601.     fixform_window( G_wi_list_adr );        /* Fixe nlle position formulaire */
  1602.  
  1603.     /*
  1604.      * Mouvement du fant“me: 
  1605.      */
  1606.     valid = drag_arboicon(    object_id, 
  1607.                                     ob_x, ob_y,
  1608.                                      ob_x + ob_w /2, ob_y + ob_h /2, 
  1609.                                     -1, -1,
  1610.                                     &drop_x, &drop_y,
  1611.                                     CTRL_OK );
  1612.  
  1613.     if( valid == POS_REPLACE_2 || valid == POS_WRONGREP_4 )
  1614.     {    /*
  1615.          * Impossible de remplacer objet
  1616.          * Fin construction ‚cran:
  1617.          */
  1618.         end_WINDRAW();
  1619.  
  1620.         form_alert( 1,  "[3][|Vous devez effacer le contenu|"
  1621.                                     "de cette case avant de pouvoir|"
  1622.                                     "y cr‚er un nouvel ‚l‚ment.]"
  1623.                                     "[Abandon]" );
  1624.                                     
  1625.         return;
  1626.     }
  1627.  
  1628.     if( valid == FALSE0 )
  1629.     {    /*
  1630.          * On a relach‚ l'ic“ne en dehors de la fenˆtre:
  1631.          * Fin construction ‚cran:
  1632.          */
  1633.         end_WINDRAW();
  1634.  
  1635.         return;
  1636.     }
  1637.  
  1638.     /*
  1639.      * ------------------------------------
  1640.      * Si on a relach‚ … un endroit valide: 
  1641.      * ------------------------------------
  1642.      */
  1643.     add_newarbo( object_id, newlink_obj, start_box, drop_x, drop_y );
  1644.     
  1645.     /*
  1646.      * Fin construction ‚cran:
  1647.      */
  1648.     end_WINDRAW();
  1649. }
  1650.  
  1651.  
  1652. /*
  1653.  * arboTree_MoveElt(-)
  1654.  *
  1655.  * Purpose:
  1656.  * --------
  1657.  * D‚placement d'un ‚l‚ment dans un dossier arborescence
  1658.  *
  1659.  * Suggest:
  1660.  * ------
  1661.  * On peut faire sans WI_PARAMS
  1662.  * ADAPTER AU MDI
  1663.  *
  1664.  * History:
  1665.  * --------
  1666.  * 10.10.94: fplanque: Created
  1667.  */
  1668. void arboTree_MoveElt(
  1669.             DATADIR    *    pDataDir,        /* In: Datadir ds lequel s'effectue le d‚placement */
  1670.             int            n_StartX,        /* In: grid pos de d‚part */
  1671.             int            n_StartY,
  1672.             int            n_DestX,            /* In: grid pos d'arriv‚e */
  1673.             int            n_DestY,
  1674.             WIPARAMS *    wi_params_adr )
  1675. {
  1676.     DIRSPEC * pDirSpec = pDataDir -> dir_spec;
  1677.     /*
  1678.      * Quel arbre d'objets: 
  1679.      * Quel objet: 
  1680.      */
  1681.     OBJECT *    pObj_Tree = wi_params_adr -> draw_ptr.tree;
  1682.     int        n_StartObjX = n_StartX * G_arbocell_w + AICON_OFFX;
  1683.     int        n_StartObjY = n_StartY * G_arbocell_h + AICON_OFFY;
  1684.     int        n_ObjIndex = find_ObjByXY( pObj_Tree, n_StartObjX, n_StartObjY );
  1685.     OBJECT *    pObject = &pObj_Tree[ n_ObjIndex ];
  1686.  
  1687.     /*
  1688.       * MAP:
  1689.      */
  1690.     unsigned    *    arbo_map     = &(pDirSpec -> dir_map)[ 2 ];    /* Tableau repr‚sentatif */
  1691.     unsigned        map_width    = (pDirSpec -> dir_map)[ 0 ];    /* Largeur tableau */
  1692.     /*
  1693.      * Nos des cases concern‚es dans le map:
  1694.      */
  1695.     int        map_SrcePos = n_StartY * map_width + n_StartX;    
  1696.     int        map_DestPos = n_DestY * map_width + n_DestX;    
  1697.  
  1698.  
  1699.     /* TRACE3( "Moving obj (%d,%d): %d", n_StartObjX, n_StartObjY, n_ObjIndex ); */
  1700.  
  1701.  
  1702.     /*
  1703.      * D‚placement dans arbre GEM:
  1704.      */
  1705.     pObject -> ob_x = n_DestX * G_arbocell_w + AICON_OFFX;
  1706.     pObject -> ob_y = n_DestY * G_arbocell_h + AICON_OFFY;
  1707.  
  1708.  
  1709.     /*
  1710.       * D‚placement dans map:
  1711.      */
  1712.     arbo_map[ map_DestPos ] = arbo_map[ map_SrcePos ];
  1713.     arbo_map[ map_SrcePos ] = 0;
  1714.  
  1715.  
  1716.     /*
  1717.      * Fixe nlles coords dans page ARBO:
  1718.      */
  1719.     if( arbo_map[ map_DestPos ] & CT_ARBO )
  1720.     {    /*
  1721.          * On a boug‚ une page arbo:
  1722.          * On recherche la page qui se trouvait 
  1723.          *    aux coordonn‚es de l'ic“ne qu'on vient d'effacer: 
  1724.          */
  1725.         DATAPAGE    *    pDataPage = find_arbo_by_xy( pDataDir, n_StartX, n_StartY );
  1726.         PAGEARBO    *    pPageArbo = pDataPage -> data.pagearbo;
  1727.  
  1728.         /* TRACE1( "Moving datapage: %lX", pDataPage ); */
  1729.  
  1730.         pPageArbo -> map_pos_x = n_DestX;            
  1731.         pPageArbo -> map_pos_y = n_DestY;
  1732.     }
  1733.     
  1734.     /* TRACE0( "  Move OK" ); */
  1735. }
  1736.  
  1737.  
  1738.  
  1739. /*
  1740.  * move_arbo(-)
  1741.  *
  1742.  * Purpose:
  1743.  * --------
  1744.  * D‚placement/Copie d'une page/lien arbo … la souris
  1745.  *
  1746.  * History:
  1747.  * --------
  1748.  * 1993: fplanque: Created
  1749.  * 06.10.94: fplanque: d‚but impl‚mentation du move:
  1750.  * 10.10.94: gestion des redraw
  1751.  */
  1752. void    move_arbo( 
  1753.             WIPARAMS *    wi_params_adr, 
  1754.             int clic_x, 
  1755.             int clic_y )
  1756. {
  1757.     /*
  1758.      * Dans quel dossier se trouve t'on ? 
  1759.      */
  1760.     DATADIR    *    datadir        = wi_params_adr -> datadir;    /* Dossier concern‚ */
  1761.     DIRSPEC    *    pDirSpec        = datadir -> dir_spec;
  1762.     unsigned        map_width    = (pDirSpec -> dir_map)[ 0 ];    /* Largeur tableau */
  1763.     unsigned    *    arbo_map     = &(pDirSpec -> dir_map)[ 2 ];    /* Tableau repr‚sentatif */
  1764.  
  1765.     /*
  1766.      * Quel arbre d'objets: 
  1767.      */
  1768.     OBJECT    *start_tree = wi_params_adr -> draw_ptr.tree;
  1769.     /*
  1770.      * Quel objet: 
  1771.      */
  1772.     int        stobj_no = wi_params_adr -> selected_icon;
  1773.     OBJECT    *stobj_adr = &start_tree[ stobj_no ];
  1774.     int        stobj_x, stobj_y;
  1775.  
  1776.     /*
  1777.      * Offset zone de travail fenˆtre: 
  1778.      */
  1779.     int    work_x = start_tree -> ob_x + AICON_OFFX;
  1780.     int    work_y = start_tree -> ob_y + AICON_OFFY;
  1781.  
  1782.     /*
  1783.      * Conversion des coordonn‚es ‚cran de la souris en coordonn‚es tableau de la case survol‚e: 
  1784.      */
  1785.     int    stcl_x    = (clic_x - work_x) /G_arbocell_w;    /* Coord X en emplacements */
  1786.     int    stcl_y    = (clic_y - work_y) /G_arbocell_h;    /* Coord Y en emplacements */
  1787.  
  1788.     /*
  1789.      * Quel est le type d'objet … d‚placer/copier: 
  1790.      */
  1791.     int        map_elt = stcl_y * map_width + stcl_x;    /* No de case dans le map */
  1792.     unsigned    object_id = arbo_map[ map_elt ];            /* Contenu de la case */
  1793.  
  1794.     /*
  1795.      * Coordonn‚es de relachement: 
  1796.      */
  1797.     int    drop_x, drop_y;
  1798.     int    destination;        /* Information sur la destination de l'icone */
  1799.  
  1800.     /* printf("%d %d -> %d Type d'objet: %X\n", stcl_x, stcl_y, map_elt, object_id ); */
  1801.  
  1802.     /*
  1803.      * Coordonn‚es de l'ic“ne de d‚part: 
  1804.      */
  1805.     objc_offset( start_tree, stobj_no, &stobj_x, &stobj_y );
  1806.  
  1807.     /*
  1808.      * Mouvement du fant“me: 
  1809.      */
  1810.     destination = drag_arboicon(    object_id, 
  1811.                                             stobj_x,    stobj_y,
  1812.                                             clic_x,    clic_y, 
  1813.                                             stcl_x,    stcl_y,
  1814.                                             &drop_x,    &drop_y,
  1815.                                             TAKE_CTRL );
  1816.  
  1817.     graf_mouse(BUSYBEE, 0);        /* Change curseur souris */
  1818.  
  1819.     /*
  1820.      * Selon destination choisie: 
  1821.      */
  1822.     if( destination < 0 )
  1823.     {    /*
  1824.          * On a d‚plac‚ l'ic“ne d'un endroit … un autre de la fenˆtre:
  1825.          */
  1826.  
  1827.         if( destination == POS_REPLACE_2 || destination == POS_WRONGREP_4 )
  1828.         {    /*
  1829.              * Si on veut remplacer un autre objet:
  1830.              * il faut effacer celui-ci au pr‚alable:
  1831.              */
  1832.  
  1833.             if( arboTree_DeleteElt( datadir, drop_x, drop_y, wi_params_adr ) == FALSE0 )
  1834.             {    /*
  1835.                  * Si on a pas effac‚:
  1836.                  */
  1837.                 return;             
  1838.             }            
  1839.         }        
  1840.  
  1841.         /*
  1842.          * On va maintenant effectuer le d‚placement r‚el:
  1843.          */
  1844.         arboTree_MoveElt( datadir, stcl_x, stcl_y, drop_x, drop_y, wi_params_adr );
  1845.  
  1846.         /*
  1847.          * R‚affichage: 
  1848.          */
  1849.         send_fullredraw( wi_params_adr );
  1850.  
  1851.     }
  1852.     else    if( destination > 0 )
  1853.     {    /*
  1854.          * Destination: une ICONE du BUREAU: 
  1855.          */
  1856.         int    resultat = IMPOSS0;        /* A priori, l'op‚ration est impossible! */
  1857.         
  1858.         /*
  1859.          * Selon destination: 
  1860.          */
  1861.         switch( destination )
  1862.         {
  1863.             case    DSTTRASH:        
  1864.                 /*
  1865.                  * Destination: CORBEILLE 
  1866.                  */
  1867.                 if ( object_id == IDELT_IN )
  1868.                 {    /*
  1869.                      * Si on essaie d'effacer le point d'entr‚e: 
  1870.                      */
  1871.                     form_alert(1,"[1][|Vous ne pouvez pas supprimer|le point d'entr‚e du dossier!][ Abandon ]");
  1872.                     resultat = ERROR_1;
  1873.                 }
  1874.                 else
  1875.                 {    /*
  1876.                      * Si on veut effacer un lien ou une page: 
  1877.                      */
  1878.                     OBJECT    *dest_adr    = &G_desktop_adr[ destination ];
  1879.  
  1880.                     /*
  1881.                      * Effet graphique: 
  1882.                      */
  1883.                     graf_beginmove( start_tree, stobj_adr, destination, dest_adr );
  1884.  
  1885.                     /*
  1886.                      * Effacement en mem et … l'‚cran:
  1887.                      */
  1888.                     if( arboTree_DeleteElt( datadir, stcl_x, stcl_y, wi_params_adr ) == TRUE_1 )
  1889.                     {    /*
  1890.                          * Si on a effac‚:
  1891.                          * Plus d'ic“ne s‚lectionn‚e: 
  1892.                          */
  1893.                         no_selection();
  1894.                         /*
  1895.                          * Modifie ligne d'informations: (Plus de s‚lection) 
  1896.                          */
  1897.                         set_infoline( wi_params_adr, arbo_infoline );
  1898.                     
  1899.                         /*
  1900.                          * R‚affichage: 
  1901.                          */
  1902.                         /* redraw( wi_params_adr, 'x' + n_ObjX, 'y' + n_ObjY, G_arbocell_w, G_arbocell_h, TAKE_CTRL ); */
  1903.                         send_fullredraw( wi_params_adr );
  1904.                     }
  1905.                 
  1906.                     resultat = OK1;    /* OK c fait (il faut d‚selectionner la destination) */
  1907.                 }
  1908.                                     
  1909.                 break;
  1910.         }    
  1911.     
  1912.         /*
  1913.          * Selon r‚sultat op‚ration: 
  1914.          */
  1915.         switch ( resultat )
  1916.         {
  1917.             case    IMPOSS0:
  1918.                 alert( PERR_IMPOSSIBLE_OP );        /* Op‚ration impossible */
  1919.                 break;
  1920.             
  1921.             case    OK1:
  1922.                 /*
  1923.                  * D‚s‚lectionne destination: 
  1924.                  */
  1925.                 modif_icon( G_desk_params_adr, destination, destination, NORMAL, TAKE_CTRL );
  1926.                 break;
  1927.                     
  1928.             case    ERROR_1:
  1929.                 /*
  1930.                  * on ne fait rien 
  1931.                  */
  1932.                 break;
  1933.                 
  1934.             default:
  1935.                 ping();
  1936.         }
  1937.     }
  1938. }
  1939.  
  1940.  
  1941.  
  1942.  
  1943. /*
  1944.  * arboTree_DeleteElt(-)
  1945.  *
  1946.  * Purpose:
  1947.  * --------
  1948.  * Efface une page d'une arborescence
  1949.  *
  1950.  * Suggest:
  1951.  * --------
  1952.  * Adapter au MDI
  1953.  *
  1954.  * History:
  1955.  * --------
  1956.  * 03.10.94: fplanque: created by moving from move_arbo()
  1957.  * 06.10.94: cherche index objet en fonction de la position, full redraw
  1958.  * 09.10.94: slight changes aiming at debugging this stuff
  1959.  * 09.10.94: remplac‚ appel de maptree() par find_ObjbySpec() : Bug corrig‚, mais pk maptree plante??
  1960.  * 10.10.94: ne provoque plus de redraw de soi-mˆme
  1961.  * 11.10.94: dplacement de la s‚lection courante si n‚cessaire
  1962.  */
  1963. int arboTree_DeleteElt(                 /* Out: TRUE si on a confim‚ effacement */
  1964.             DATADIR    *    datadir,
  1965.             int            mapPos_x,        /* In: Coordonn‚es de l'elt … effacer dans le tableau */
  1966.             int            mapPos_y,
  1967.             WIPARAMS *    wi_params_adr )
  1968. {
  1969.     int        effacement    = NO0;                        /* A propri, on efface pas sans confirmation */
  1970.  
  1971.     DIRSPEC * pDirSpec = datadir -> dir_spec;
  1972.     
  1973.     /*
  1974.       * MAP:
  1975.      */
  1976.     unsigned    *    arbo_map     = &(pDirSpec -> dir_map)[ 2 ];    /* Tableau repr‚sentatif */
  1977.     unsigned        map_width    = (pDirSpec -> dir_map)[ 0 ];    /* Largeur tableau */
  1978.     /*
  1979.      * No de case '… vider' dans le map:
  1980.      */
  1981.     int        map_elt = mapPos_y * map_width + mapPos_x;    
  1982.     /*
  1983.      * Type d'objet se trouvant … cet endroit:
  1984.      */
  1985.     unsigned    object_id = arbo_map[ map_elt ];            /* Contenu de la case */
  1986.  
  1987.     /*
  1988.      * Quel arbre d'objets: 
  1989.      * Quel objet: 
  1990.      */
  1991.     OBJECT *    pObj_Tree = wi_params_adr -> draw_ptr.tree;
  1992.     int        n_ObjX     = mapPos_x * G_arbocell_w + AICON_OFFX;
  1993.     int        n_ObjY     = mapPos_y * G_arbocell_h + AICON_OFFY;
  1994.     int        n_ObjIndex = find_ObjByXY( pObj_Tree, n_ObjX, n_ObjY );
  1995.     OBJECT *    pObject    = &pObj_Tree[ n_ObjIndex ];
  1996.     /*
  1997.       * Nbre d'objets:
  1998.      * (Non compris le ROOT ni le lien 'IN')
  1999.      */
  2000.     int        nb_objs = pDirSpec -> nb_objs;
  2001.  
  2002.     /* TRACE0( "-------------delete--------------" ); */
  2003.     /* TRACE1( "Nb objs before erase: %d", nb_objs ); */
  2004.  
  2005.     /*
  2006.      * Anti Stuck:
  2007.      */
  2008.     if( n_ObjIndex == -1 )
  2009.     {
  2010.         signale( "arboTree_DeleteElt() n'a pas trouv‚ l'elt … effacer!" );
  2011.         return    FALSE0;
  2012.     }
  2013.  
  2014.  
  2015.     /*
  2016.      * Teste si on efface une page: 
  2017.      */
  2018.     if( object_id & CT_ARBO )
  2019.     {    /*
  2020.          * On efface une page: 
  2021.          * On va donc supprimer les donn‚es de la page: 
  2022.          *
  2023.          * On recherche la page qui se trouvait 
  2024.          *    aux coordonn‚es de l'ic“ne qu'on vient d'effacer: 
  2025.          */
  2026.         DATAPAGE    *datapage = find_arbo_by_xy( datadir, mapPos_x, mapPos_y );
  2027.         
  2028.         /*
  2029.          * Demande conf & Supprime la page: 
  2030.          */
  2031.         if( efface_1data( datadir, datapage ) )
  2032.         {    /*
  2033.              * Si on a effac‚: 
  2034.              */
  2035.             effacement = YES1;
  2036.         }
  2037.     }
  2038.     else
  2039.     {    /*
  2040.          * Si on efface un lien: 
  2041.           * On ne demande pas de confirmation
  2042.          */
  2043.         effacement = YES1;    /* OK on peut effacer */
  2044.     }
  2045.  
  2046.  
  2047.     if( effacement == FALSE0 )
  2048.     {    /*
  2049.           * On n'a pas confirm‚!!:
  2050.          */
  2051.         return    FALSE0;
  2052.     }
  2053.  
  2054.     /*
  2055.      * -------------------------
  2056.       * On enlŠve l'objet du MAP:
  2057.      * Effacement logique du map: 
  2058.      */
  2059.     arbo_map[ map_elt ] = 0;    /* Case VIDE */
  2060.  
  2061.     /*
  2062.      * Teste s'il s'agit d'une ic“ne: 
  2063.      */
  2064.     if( (pObj_Tree[ n_ObjIndex ] .ob_type & 0x00FF) == G_ICON )
  2065.     {    /*
  2066.          * S'il s'agit d'une ic“ne: 
  2067.          * Il va falloir supprimer l'ICONBLK: 
  2068.          */
  2069.         ICONBLK    *    rm_iblk;
  2070.         ICONBLK    *    iconblks;
  2071.         int            nb_iblks;
  2072.         ICONBLK    *    last_iblk;
  2073.                                         
  2074.         /* IBLK … supprimer */
  2075.         rm_iblk = pObj_Tree[ n_ObjIndex ] .ob_spec.iconblk;    
  2076.  
  2077.         /* Tableau d'IBLKs du dossier */
  2078.         iconblks = datadir -> iconblks;
  2079.     
  2080.         /* Nbre d'IBLKS dans le dossier */
  2081.         nb_iblks = pDirSpec -> nb_iblks;        
  2082.     
  2083.         /* Ptr sur dernier IBLK */
  2084.         last_iblk = &iconblks[ nb_iblks-1 ];    
  2085.  
  2086.         /*
  2087.          * Teste si on invalide le dernier ICONBLK ou pas: 
  2088.          */
  2089.         if( rm_iblk < last_iblk )
  2090.         {    /*
  2091.              * On n'a pas invalid‚ le dernier ICONBLK... 
  2092.              * Il y a donc un trou qu'il faut combler! 
  2093.              * Recopie le dernier IBLK vers le trou: 
  2094.              */
  2095.             int             idx;
  2096.             OBJECT    *    pObj_Owner;
  2097.  
  2098.             /* TRACE2( "  Moving ICONBLK: %lX -> %lX", last_iblk, rm_iblk ); */
  2099.  
  2100.             memcpy( rm_iblk, last_iblk, sizeof( ICONBLK ) );
  2101.             
  2102.             /*
  2103.              * Recherche l'objet … qui appartenait le dernier IBLK 
  2104.              */
  2105.             /* M_searched_iblk = last_iblk;            /* IBLK dont on recherche le propri‚taire */
  2106.             /* M_iblk_owner = NULL; */
  2107.             /* maptree( pObj_Tree, 2, nb_objs + 1, iblk_owner ); */
  2108.  
  2109.             idx = find_ObjBySpec( pObj_Tree,    last_iblk );
  2110.             pObj_Owner = &(pObj_Tree[idx] );
  2111.  
  2112.             if( pObj_Owner < pObj_Tree )
  2113.             {
  2114.                 signale( "Could not find IBLK owner!" );
  2115.             }
  2116.             
  2117.             /* TRACE2( "  OBJECT=%lX has last IBLK:%lX", pObj_Owner, pObj_Owner -> ob_spec.iconblk ); */
  2118.  
  2119.             /*
  2120.              * Change pointeur vers le nouvel iblk, 
  2121.              * celui qui bouche le trou; afin de lib‚rer le dernier: 
  2122.              */
  2123.             pObj_Owner -> ob_spec.iconblk = rm_iblk;
  2124.             
  2125.         }
  2126.  
  2127.         /*
  2128.          * 1 ICONBLK de moins: 
  2129.          */
  2130.         (pDirSpec -> nb_iblks) --;
  2131.     }
  2132.  
  2133.     /*
  2134.      * EnlŠve les liens sur l'objet: 
  2135.      */
  2136.     objc_delete( pObj_Tree, n_ObjIndex );
  2137.  
  2138.  
  2139.     /*
  2140.      * Teste si on a supprim‚ le dernier objet ou pas: 
  2141.      */
  2142.     if( n_ObjIndex < nb_objs )
  2143.     {    /*
  2144.          * Si on a pas supprim‚ le dernier objet: 
  2145.          */
  2146.  
  2147.         /*
  2148.          * ATTENTION au trou cr‚‚ dans l'arbre!!... 
  2149.          * On va ramener le dernier objet … la place 
  2150.          * de celui qu'on vient d'enlever! 
  2151.          * EnlŠve les liens sur le dernier objet: 
  2152.          */
  2153.  
  2154.         objc_delete( pObj_Tree, nb_objs );
  2155.         /*
  2156.          * L'objet enlev‚ n'est plus le dernier elt de l'arbre:
  2157.          */
  2158.         pObj_Tree[ nb_objs ] .ob_flags &= ~LASTOB;
  2159.         /*
  2160.          * Recopie cet objet dans le trou cr‚‚ plus haut: 
  2161.          */
  2162.         memcpy( pObject, &pObj_Tree[ nb_objs ], sizeof( OBJECT ) );
  2163.         /*
  2164.          * Recr‚e les liens entre l'objet d‚plac‚ et l'arbre: 
  2165.          */
  2166.         objc_add( pObj_Tree, ROOT, n_ObjIndex );
  2167.         /*
  2168.          * Fixe nouveau LASTOB:
  2169.          */
  2170.         pObj_Tree[ nb_objs -1 ] .ob_flags |= LASTOB;
  2171.         
  2172.         
  2173.         /*
  2174.          * Mise … jour de la s‚lection courante si elle a ‚t‚ d‚plac‚e:
  2175.          * ATTENTION: pas compatible MDI: la s‚lection pourrait ˆtre ds une autre fenˆtre
  2176.          */
  2177.         if( wi_params_adr -> selected_icon == nb_objs )
  2178.         {
  2179.             /* TRACE2( "CHANGING s‚lection from %d to %d", nb_objs, n_ObjIndex ); */
  2180.             wi_params_adr -> selected_icon = n_ObjIndex;
  2181.         }
  2182.     }
  2183.  
  2184.     /*
  2185.      *    Un objet de moins dans l'arbre: 
  2186.      */
  2187.     (pDirSpec -> nb_objs) --;
  2188.  
  2189.     return    TRUE_1;
  2190.     
  2191. }
  2192.  
  2193.  
  2194. #ifdef    NOTDEFINED
  2195. /*
  2196.  * iblk_owner(-)
  2197.  *
  2198.  * Purpose:
  2199.  * --------
  2200.  * Subroutine from MAPTREE: 
  2201.  * Recherche le propri‚taire d'un ICONBLK donn‚
  2202.  *
  2203.  * History:
  2204.  * --------
  2205.  * 1993: fplanque: Created
  2206.  */
  2207. int    iblk_owner( OBJECT *tree, int obj )
  2208. {
  2209.     OBJECT    *    pObject = &tree[ obj ];
  2210.     
  2211.     if ( (pObject -> ob_type & 0x00FF) == G_ICON )
  2212.     {    /*
  2213.          * S'il s'agit d'une ic“ne: 
  2214.          */    
  2215.         /* TRACE2( "MapTree: examine obj %lX IBLK=%lX", pObject, pObject -> ob_spec.iconblk ); */
  2216.         if( pObject -> ob_spec.iconblk == M_searched_iblk )
  2217.         {    /*
  2218.               * Si on a trouv‚ le propri‚taire: 
  2219.              */
  2220.             /* TRACE0( "Found sought IBLK!" ); */
  2221.  
  2222.             M_iblk_owner = pObject;
  2223.  
  2224.             return    FALSE0;    /* On arrˆte la recherche */
  2225.         }
  2226.     }
  2227.     
  2228.     return    TRUE_1;    /* On continue … chercher */
  2229. }
  2230. #endif 
  2231.  
  2232.  
  2233. /*
  2234.  * drag_arboicon(-)
  2235.  *
  2236.  * Purpose:
  2237.  * --------
  2238.  * D‚placement d'un fant“me d'ic“ne    
  2239.  *
  2240.  * History:
  2241.  * --------
  2242.  * 1993: fplanque: Created
  2243.  * 10.10.94: contr“le si coord drop = init
  2244.  */
  2245. int    drag_arboicon(                        /* Out: Code indiquant le type de destination */
  2246.             unsigned        object_id, 
  2247.             int            ob_x,             /* In: Pos de l'objet au d‚part */
  2248.             int            ob_y, 
  2249.             int            start_x,         /* In: position de la souris au d‚part */
  2250.             int            start_y, 
  2251.             int            n_GridSrceX,    /* In: Coordonn‚es de d‚part ds la grille */
  2252.             int            n_GridSrceY,
  2253.             int        *    drop_x,             /* In: Grid coord de relƒchement */
  2254.             int        *    drop_y,
  2255.             int             take_control )    /* In: faut il prendre le controle de l'‚cran ou pas? */
  2256. {
  2257.     int        drag_evt;            /* EvŠnement qui s'est d‚clench‚: */
  2258.     int        new_bstate, kbd_state, kbd_return, mouse_nbc;    /* Non utilis‚s */
  2259.  
  2260.     int        offset_x , offset_y;
  2261.     int        fantome_x, fantome_y;
  2262.     int        area_x1, area_y1, area_x2, area_y2;    /* Zone de d‚placement du fant“me */
  2263.     int        new_x, new_y;        /* Nlle position souris */
  2264.  
  2265.     int        new_handle;            /* Handle de la fen point‚e par la souris */
  2266.     int        i,j;
  2267.     
  2268.     /*
  2269.      * Offset zone de travail fenˆtre: 
  2270.      */
  2271.     int    work_x = (G_wi_list_adr -> draw_ptr.tree) -> ob_x + AICON_OFFX;
  2272.     int    work_y = (G_wi_list_adr -> draw_ptr.tree) -> ob_y + AICON_OFFY;
  2273.  
  2274.     /*
  2275.      * Proposition: 
  2276.      */
  2277.         /*
  2278.          * Dans la fenˆtre arbo: 
  2279.          */
  2280.         int    prop_x, prop_y;        /* Coordonn‚es ‚cran */
  2281.         int    old_x=-1, old_y=-1;    /* Coord ‚cran ancien placement */
  2282.         int    line_style=0;            /* Style de trait pour la proposition */
  2283.         /*
  2284.          * Sur le bureau: 
  2285.          */
  2286.         int    last_spot=-1;            /* Dernier objet que l'on avait "allum‚" */
  2287.     
  2288.     /*
  2289.      * Clipping des possibilit‚s de proposition: 
  2290.      * On prend le rectangle le plus restreint entre la zone de travail
  2291.      *        de la fenˆtre et la taille de la boŒte pŠre: 
  2292.      */
  2293.         G_cliparray[ 0 ]    =    max( G_wi_list_adr -> work_x, work_x );
  2294.         G_cliparray[ 1 ]    =    max( G_wi_list_adr -> work_y, work_y );
  2295.         G_cliparray[ 2 ]    =    min( G_wi_list_adr -> work_x + G_wi_list_adr -> seen_w -1,
  2296.                                         work_x + (G_wi_list_adr -> draw_ptr.tree) -> ob_width -1 -WA_BORDER);
  2297.         G_cliparray[ 3 ]    =    min( G_wi_list_adr -> work_y + G_wi_list_adr -> seen_h -1,
  2298.                                         work_y + (G_wi_list_adr -> draw_ptr.tree) -> ob_height -1 -WA_BORDER);
  2299.         /*    printf("%d %d %d %d\n", G_cliparray[ 0 ], G_cliparray[ 1 ], G_cliparray[ 2 ], G_cliparray[ 3 ]); */
  2300.         
  2301.     /* 
  2302.      * Simule "construction ‚cran" pour empˆcher l'AES de d‚rouler ses menus: 
  2303.      */
  2304.     /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
  2305.     if( take_control == TAKE_CTRL )
  2306.     {
  2307.         start_WINDRAW( NULL );
  2308.     }
  2309.  
  2310.     /*
  2311.      * Forme souris: 
  2312.      */
  2313.     graf_mouse( FLAT_HAND, NULL );    /* Main ouverte */
  2314.  
  2315.     /*
  2316.      * Calcule la zone ds laquelle peut se d‚placer le fant“me: 
  2317.      */    
  2318.     area_x1 = G_x_mini;
  2319.     area_y1 = G_y_mini;
  2320.     area_x2 = G_x_mini + G_w_maxi - M_arboelt_w;    /* Taille de ce type */
  2321.     area_y2 = G_y_mini + G_h_maxi - M_arboelt_h;    /* d'ic“nes */
  2322.     
  2323.     /*
  2324.      * Calcule offset entre ic“ne-start et pointeur de la souris: 
  2325.      */
  2326.     offset_x = ob_x - start_x;
  2327.     offset_y = ob_y - start_y;
  2328.  
  2329.     /*
  2330.      * Nouvelle position par d‚faut: 
  2331.      */
  2332.     new_x = start_x;
  2333.     new_y = start_y;
  2334.  
  2335.     /*
  2336.      * Fixe les paramŠtres de dessin VDI: 
  2337.      */
  2338.     vsl_color( G_ws_handle, RED );                    /* Couleur */        
  2339.     vswr_mode( G_ws_handle, MD_XOR );                /* Mode XOR */
  2340.     vsl_type( G_ws_handle, 7 );                        /* Motif utilisateur */
  2341.             
  2342.     /*
  2343.      * --------------------
  2344.      * Boucle de mouvement: 
  2345.      * --------------------
  2346.      */
  2347.     do
  2348.     {    /*
  2349.          * Cherche sur quoi se trouve le pointeur de la souris: 
  2350.          */            
  2351.         new_handle = wind_find( new_x, new_y );
  2352.  
  2353.         /*
  2354.          * Selon la fenˆtre "survol‚ee": 
  2355.          */
  2356.         if ( new_handle == G_top_wi_handle )
  2357.         {    /*
  2358.              * Si on est dans la fenˆtre concern‚e: 
  2359.              */
  2360.             if ( new_x >= G_cliparray[ 0 ]
  2361.                     && new_y    >= G_cliparray[ 1 ]
  2362.                     && new_x    <= G_cliparray[ 2 ]
  2363.                     && new_y    <= G_cliparray[ 3 ] )
  2364.             {    /*
  2365.                  * Conversion des coordonn‚es ‚cran de la souris
  2366.                  * en coordonn‚es tableau de la case survol‚e: 
  2367.                  */
  2368.                 *drop_x    = (new_x - work_x) /G_arbocell_w;    /* Coord X en emplacements */
  2369.                 prop_x    = work_x + *drop_x * G_arbocell_w;    /* Coord X ‚cran */
  2370.  
  2371.                 *drop_y    = (new_y - work_y) /G_arbocell_h;    /* Coord Y en emplacements */
  2372.                 prop_y    = work_y + *drop_y * G_arbocell_h;    /* Coord Y ‚cran */
  2373.  
  2374.                 /*
  2375.                  * Teste si la proposition … chang‚: 
  2376.                  */
  2377.                 if ( old_x != prop_x || old_y != prop_y )
  2378.                 {    /*
  2379.                      * Si la proposition … chang‚: 
  2380.                      * ParamŠtres VDI: 
  2381.                      */
  2382.                     vs_clip( G_ws_handle, 1, G_cliparray );    /* Clipping sur work */
  2383.     
  2384.                     /*
  2385.                      * Teste s'il faut effacer l'ancienne: 
  2386.                      */
  2387.                     if ( old_x != -1 && line_style !=0 )
  2388.                     {    /*
  2389.                          * S'il y avait d‚j… une proposition affich‚e: 
  2390.                          * Efface la proposition de placement: 
  2391.                          */
  2392.                         vsl_type( G_ws_handle, line_style );    /* Type de trait */
  2393.                         draw_proposition(); 
  2394.                     }
  2395.     
  2396.                     /*
  2397.                      * ------------------------------------------
  2398.                      * Teste si le nouveau placement est correct: 
  2399.                      * ------------------------------------------
  2400.                      */
  2401.                     control_links( object_id, 
  2402.                                         *drop_x, *drop_y, 
  2403.                                         n_GridSrceX, n_GridSrceY,
  2404.                                         &line_style );
  2405.     
  2406.                     if( line_style )
  2407.                     {    /*
  2408.                          * S'il faut afficher 
  2409.                          * Fixe coordonn‚es du nouveau dessin: 
  2410.                          */
  2411.                         for( i=1, j=0; i<=5; i++ )
  2412.                         {
  2413.                             G_pxyarray2[ j ]= prop_x + M_fantome_lien[ j++ ];
  2414.                             G_pxyarray2[ j ]= prop_y + M_fantome_lien[ j++ ];
  2415.                         }
  2416.         
  2417.                         /*
  2418.                          * Dessin de la proposition de placement: 
  2419.                          */
  2420.                         vsl_type( G_ws_handle, line_style );    /* Type de trait */
  2421.                         draw_proposition(); 
  2422.         
  2423.                     }                            
  2424.     
  2425.                     /*
  2426.                      * ParamŠtres VDI: 
  2427.                      */
  2428.                     vsl_type( G_ws_handle, 7 );        /* Motif utilisateur */
  2429.                     vs_clip( G_ws_handle, 0, G_cliparray );    /* Clipping OFF! */
  2430.     
  2431.                     /*
  2432.                      * Nouvelle "ancienne" proposition: 
  2433.                      */
  2434.                     old_x = prop_x;
  2435.                     old_y    = prop_y;
  2436.  
  2437.                 }
  2438.             }
  2439.         }
  2440.         else
  2441.         {    /*
  2442.              * Si pas ds fen concern‚e: 
  2443.              * Teste s'il faut effacer la proposition courante: 
  2444.              */
  2445.             if ( old_x != -1 )
  2446.             {    /*
  2447.                  * S'il y avait une proposition: 
  2448.                  */
  2449.  
  2450.                 if( line_style != 0 )
  2451.                 {    /*
  2452.                      * Si elle ‚tait affich‚e: 
  2453.                      * ParamŠtres VDI: 
  2454.                      */
  2455.                     vsl_type( G_ws_handle, line_style );    /* Type de trait */
  2456.                     vs_clip( G_ws_handle, 1, G_cliparray );    /* Clipping sur work */
  2457.                     /*
  2458.                      * Efface la proposition de placement: 
  2459.                      */
  2460.                     draw_proposition(); 
  2461.                     /*
  2462.                      * ParamŠtres VDI: 
  2463.                      */
  2464.                     vsl_type( G_ws_handle, 7 );        /* Motif utilisateur */
  2465.                     vs_clip( G_ws_handle, 0, G_cliparray );    /* Clipping OFF! */
  2466.                 }
  2467.                 
  2468.                 /*
  2469.                  * Plus de proposition: 
  2470.                  */
  2471.                 old_x = -1;
  2472.                 old_y = -1;
  2473.             }                                            
  2474.         
  2475.             /*
  2476.              * Teste ‚ventuellement les ic“nes du bureau: 
  2477.              */
  2478.             sensitive_desk( new_x, new_y, NIL, &last_spot );
  2479.         }
  2480.     
  2481.         /*
  2482.          * Coordonn‚es auxquelles il faut dessiner le fant“me: 
  2483.          */
  2484.         fantome_x = new_x + offset_x;
  2485.         if ( fantome_x < area_x1 )
  2486.             fantome_x = area_x1;
  2487.         else if ( fantome_x > area_x2 )
  2488.             fantome_x = area_x2;
  2489.         
  2490.         fantome_y = new_y + offset_y;
  2491.         if ( fantome_y < area_y1 )
  2492.             fantome_y = area_y1;
  2493.         else if ( fantome_y > area_y2 )
  2494.             fantome_y = area_y2;
  2495.         
  2496.         /*
  2497.          * Fixe coordonn‚es du dessin: 
  2498.          */
  2499.         for( i=1, j=0; i<=5; i++ )
  2500.         {
  2501.             G_pxyarray[ j ]= fantome_x + M_fantome_lien[ j++ ];
  2502.             G_pxyarray[ j ]= fantome_y + M_fantome_lien[ j++ ];
  2503.         }
  2504.         
  2505.         /*
  2506.          * --------------------
  2507.          * Dessin du fant“me de l'ic“ne: 
  2508.          * --------------------
  2509.          */
  2510.         rig_draw_fantom(); 
  2511.             
  2512.         /*
  2513.          * Attend qu'il se passe qque chose: 
  2514.          */
  2515.         drag_evt=evnt_multi( MU_BUTTON | MU_M1,
  2516.                                 1, 1, 0,                            /* Observe le relachement du bouton gauche */
  2517.                         1, new_x, new_y, 1, 1,        /* Observe tout d‚placement de la souris */ 
  2518.                         0, 0, 0, 0, 0,
  2519.                         0L, 
  2520.                         0, 0,
  2521.                         &new_x, &new_y, &new_bstate,
  2522.                         &kbd_state, &kbd_return,
  2523.                         &mouse_nbc);
  2524.         /*    printf("%d \r",new_bstate ); */
  2525.  
  2526.         /*
  2527.          * Efface le fant“me de l'ic“ne: 
  2528.          */
  2529.         rig_draw_fantom(); 
  2530.         
  2531.     } while( drag_evt != MU_BUTTON );
  2532.  
  2533.     
  2534.     /*
  2535.      * Il faut remettre en place certains attributs de dessin: 
  2536.      */
  2537.     vswr_mode( G_ws_handle, MD_REPLACE );            /* FIN Mode XOR */
  2538.  
  2539.     /*
  2540.      * Si on … relach‚ sur une icone: 
  2541.      */
  2542.     if ( last_spot != NIL )
  2543.     {    /*
  2544.          * D‚s‚lectionne l'ic“ne destination: 
  2545.          */
  2546.         modif_icon( G_desk_params_adr, last_spot, last_spot, NORMAL, CTRL_OK );    /* D‚S‚lectionne */
  2547.     }
  2548.  
  2549.     /*
  2550.      * Fin du drag 
  2551.      */
  2552.     graf_mouse(BUSYBEE, 0);            /* Change curseur souris */
  2553.  
  2554.     if( take_control == TAKE_CTRL )
  2555.     {
  2556.         end_WINDRAW();
  2557.     }
  2558.     /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
  2559.  
  2560.     /*
  2561.      * Teste si on a relach‚ le fant“me … un emplacement valide: 
  2562.      */
  2563.     /* printf( "Old_x=%d Last_spot=%d ", old_x, last_spot ); */
  2564.     if ( old_x != -1 )
  2565.     {     /*
  2566.          * Si on a une proposition dans la fenetre: 
  2567.          */
  2568.         switch ( line_style )
  2569.         {
  2570.             case    LSTYL_OK:
  2571.                 return    POS_FREE_1;        
  2572.                 
  2573.             case    LSTYL_REPLACE:
  2574.                 return    POS_REPLACE_2;
  2575.         
  2576.             case    LSTYL_WRONG:
  2577.                 return    POS_ISOLATED_3;
  2578.  
  2579.             case    LSTYL_WRONGREP:
  2580.                 return    POS_WRONGREP_4;
  2581.     
  2582.             /* case LSTYL_NOWAY: */
  2583.             default:
  2584.                 return    FALSE0;        /* Aucune dest valide */
  2585.         }
  2586.     }
  2587.     else if ( last_spot != NIL )
  2588.     {    /*
  2589.          * Si on a d‚plac‚ vers une icone: 
  2590.          */
  2591.         return    last_spot;            /* Retourne no de cette icone */
  2592.     }
  2593.  
  2594.     /*
  2595.      * Par d‚faut: 
  2596.      */
  2597.     return    FALSE0;            /* Aucune destination valide */
  2598.  
  2599. }
  2600.  
  2601.  
  2602.  
  2603.  
  2604. /*
  2605.  * control_links(-)
  2606.  *
  2607.  * Purpose:
  2608.  * --------
  2609.  * Contr“le si le placement propos‚ est correct
  2610.  *
  2611.  * History:
  2612.  * --------
  2613.  * 1993: fplanque: Created
  2614.  * 10.10.94: fplanque: V‚rifie position initiale
  2615.  * 11.10.94: ajout style LSTYL_WRONGREP
  2616.  */
  2617. void    control_links( 
  2618.             unsigned object_id, 
  2619.             int         pos_x,         /* In: Position propos‚e */
  2620.             int         pos_y, 
  2621.             int        n_StartX,    /* In: Position initiale */
  2622.             int        n_StartY,
  2623.             int *        line_style )
  2624. {
  2625.     int            pos_error    =    0;        /* A priori, pas d'erreur de positionnement */
  2626.     /*
  2627.     * Adresse du map: 
  2628.      */
  2629.     DIRSPEC    *    pDirSpec = G_wi_list_adr -> datadir -> dir_spec;
  2630.     unsigned    *    arbo_map = pDirSpec -> dir_map; /* Avant, on prenait le datadir, ds le content */
  2631.     unsigned        map_width = arbo_map[ 0 ];        /* Largeur du tableau */
  2632.     unsigned        map_height = arbo_map[ 1 ];    /* Hauteur du tableau */
  2633.     unsigned        concerned;                /* No/case concern‚e */
  2634.  
  2635.     /* printf("Pos: %d %d \n", pos_x, pos_y ); */
  2636.  
  2637.     /*
  2638.      * Teste si les coordonn‚es de relƒchement sont ‚gales
  2639.      * aux coordon‚es de d‚part:
  2640.      */
  2641.     if( pos_x == n_StartX && pos_y == n_StartY )
  2642.     {    /*
  2643.          * On n'autorise pas cette position:
  2644.          */
  2645.         *line_style = LSTYL_NOWAY;
  2646.         return;
  2647.     }
  2648.  
  2649.  
  2650.     /*
  2651.      * Contr“le lien North: 
  2652.      */
  2653.     if (    object_id & IN_NORTH        /* Si nl objet … un lien IN au nord: */
  2654.         && (    pos_y == 0                    /* et si on est en ligne 0 */
  2655.             ||    ( (arbo_map[ (pos_y-1) * map_width + pos_x +2 ] & OUT_SOUTH) == 0 )
  2656.             )                                    /* ou objet au dessus n'a pas de lien OUT au sud */
  2657.         )
  2658.     {
  2659.         pos_error  = 1;            /* Il y a une erreur de lien */
  2660.     }
  2661.  
  2662.     /*
  2663.      * Contr“le lien West: 
  2664.      */
  2665.     concerned = pos_y * map_width + pos_x-1 +2;
  2666.     if (    object_id & IN_WEST    )    /* Si nl objet … un lien IN … l'ouest: */
  2667.     {
  2668.         if    (    pos_x == 0                    /* et si on est en col 0 */
  2669.             ||    ( (arbo_map[ concerned ] & OUT_EAST) == 0 )
  2670.             )                                    /* ou objet … gauche n'a pas de lien OUT … l'est */
  2671.         {
  2672.             pos_error  = 1;            /* Il y a une erreur de lien */
  2673.         }
  2674.     }
  2675.     else if (    object_id & OUT_WEST    )    /* Si nl objet … un lien OUT … l'ouest: */
  2676.     {
  2677.         if (    pos_x == 0                    /* et si on est en col 0 */
  2678.             || (    arbo_map[ concerned ] != 0    /* ou case … gauche pas vide */
  2679.                 &&    (arbo_map[ concerned ] & IN_EAST) == 0 /* et case a gauche ss entr‚e EST */
  2680.                 )
  2681.             )
  2682.         {
  2683.             pos_error  = 1;            /* Il y a une erreur de lien */
  2684.         }
  2685.     }
  2686.  
  2687.     /*
  2688.      * Contr“le lien East: 
  2689.      */
  2690.     concerned = pos_y * map_width + pos_x+1 +2;
  2691.     if (    object_id & IN_EAST )    /* Si nl objet … un lien IN … l'est: */
  2692.     {
  2693.         if (    pos_x == map_width -1    /* et si on est en col maxi */
  2694.             ||    ( (arbo_map[ concerned ] & OUT_WEST) == 0 )
  2695.             )                                    /* ou objet … droite n'a pas de lien OUT … l'ouest */
  2696.         {
  2697.             pos_error  = 1;            /* Il y a une erreur de lien */
  2698.         }
  2699.     }
  2700.     else if ( object_id & OUT_EAST )    /* Si nl objet … un lien OUT … l'est: */
  2701.     {
  2702.         if (    pos_x == map_width -1    /* et si on est en col maxi */
  2703.             || (    arbo_map[ concerned ] != 0    /* ou case … doite pas vide */
  2704.                 &&    (arbo_map[ concerned ] & IN_WEST) == 0 /* ou case … droite ss entr‚e … l'OUEST */
  2705.                 )
  2706.             )
  2707.         {
  2708.             pos_error  = 1;            /* Il y a une erreur de lien */
  2709.         }
  2710.     }
  2711.  
  2712.     /*
  2713.      * Contr“le lien South: 
  2714.      */
  2715.     concerned = (pos_y+1) * map_width + pos_x +2;
  2716.     if ( object_id & OUT_SOUTH     /* Si nl objet … un lien OUT au sud: */
  2717.         &&    (    pos_y == map_height -1    /* et si on est en ligne maxi */
  2718.             || (    arbo_map[ concerned ] != 0    /* ou case en dessous pas vide */
  2719.                 &&    (arbo_map[ concerned ] & IN_NORTH) == 0 /* ou case au dessous ss entr‚e au nord */
  2720.                 )
  2721.             )
  2722.         )
  2723.     {
  2724.         pos_error  = 1;            /* Il y a une erreur de lien */
  2725.     }
  2726.  
  2727.     /*
  2728.       * Case concern‚e 
  2729.      */
  2730.     concerned = arbo_map[ pos_y * map_width + pos_x +2 ];
  2731.         
  2732.     /*
  2733.      * Contr“le ‚ventualit‚ de remplacement: 
  2734.      * (case d‚j… occup‚e)
  2735.      */
  2736.     if( concerned != 0 )
  2737.     {    /*
  2738.          * emplacement d‚j… utilis‚: 
  2739.          */
  2740.         if( pos_error == 0 )
  2741.         {    /*
  2742.              * Si pas d'erreur de liens:
  2743.              */
  2744.             pos_error = 2;
  2745.         }
  2746.         else
  2747.         {    /*
  2748.              * Non seulement, on va remplacer, mais en plus
  2749.              * les liens sont incorrect pour la case targett‚e
  2750.              */
  2751.             pos_error = 3;
  2752.         }
  2753.     }
  2754.     
  2755.     /*
  2756.      * R‚agit en fonction de l'erreur 
  2757.      */
  2758.     switch ( pos_error )
  2759.     {
  2760.         case 0:                    /* pas d'erreur */
  2761.             *line_style = LSTYL_OK;            /* Tait continu */
  2762.             break;
  2763.             
  2764.         case 1:                    /* Erreur de liens */
  2765.             *line_style = LSTYL_WRONG;        /* petits points */
  2766.             break;
  2767.             
  2768.         case 2:                    /* Erreur de superposition */
  2769.             *line_style = LSTYL_REPLACE;    /* Longs Pointill‚s */
  2770.             break;
  2771.             
  2772.         case 3:                    /* Erreur de superposition + de liens */
  2773.             *line_style = LSTYL_WRONGREP;    /* Pointill‚s */
  2774.             break;
  2775.             
  2776.         default:
  2777.             signale( "Ne peut d‚terminer autorisation de pos" );
  2778.     }
  2779.  
  2780. }
  2781.  
  2782.  
  2783. /*
  2784.  * link_arbo_to_parent(-)
  2785.  *
  2786.  * Purpose:
  2787.  * --------
  2788.  * Liaison d'une nouvelle page arbo … son pŠre
  2789.  *
  2790.  * History:
  2791.  * --------
  2792.  * 1993: fplanque: Created
  2793.  * 17.12.94: impl‚ment‚ retour par sommaire, retour, envoi
  2794.  * 17.12.94: quelques liens descendants
  2795.  * 12.04.95: enhanced
  2796.  */
  2797. void    link_arbo_to_parent( 
  2798.             DATADIR *    datadir, 
  2799.             int             pos_x, 
  2800.             int             pos_y )
  2801. {
  2802.     DATAPAGE    *    pDataPage_curr = find_arbo_by_xy( datadir, pos_x, pos_y );
  2803.     PAGEARBO    *    pPageArbo_curr = pDataPage_curr -> data.pagearbo;
  2804.     int            ascent_x, ascent_y;        /* Coordonn‚es de l'ancˆtre */
  2805.     unsigned        u_ParentCell;
  2806.     int            n_FnctCurr = pPageArbo_curr -> fnct_no;
  2807.     int            n_FnctParent;
  2808.  
  2809.     /* printf("\033Y! "); */
  2810.     /* printf("Nouvelle page: %s\n", pDataPage_curr -> nom ); */
  2811.  
  2812.     /*
  2813.      * Parcourt les liens en remontant … la recherche de l'ancˆtre 
  2814.      *    de la page courante: 
  2815.      */
  2816.     u_ParentCell = find_ascent( datadir, pos_x, pos_y, &ascent_x, &ascent_y );
  2817.  
  2818.     if( u_ParentCell & CT_ARBO )
  2819.     {    /*
  2820.          * Si le parent est une page arbo (cas classique): 
  2821.          */
  2822.         DATAPAGE    *    pDataPage_parent = find_arbo_by_xy( datadir, ascent_x, ascent_y );    /* Trouve le parent */
  2823.         PAGEARBO    *    pPageArbo_parent = pDataPage_parent -> data.pagearbo;
  2824.         n_FnctParent = pPageArbo_parent -> fnct_no;
  2825.         
  2826.         /*
  2827.          * ------------------------------------
  2828.          * Retour du descendant vers son parent
  2829.          * ------------------------------------
  2830.          * Certains parents ne sont pas vraiment pr‚vus pour un retour
  2831.          * on s‚lectionne ici:
  2832.          */
  2833.         switch( n_FnctParent )
  2834.         {
  2835.             case    FA_MENU:
  2836.             case    FA_LECT_MSG:
  2837.             case    FA_DISP_TEXT:
  2838.             case    FA_LIST:
  2839.             case    FA_DIRECTORY:
  2840.             case    FA_FILESEL:
  2841.                 /*
  2842.                  * Ces types la acceptent le retour de bon coeur:
  2843.                  * Les possibilit‚s de retour sont diff‚rentes selon 
  2844.                  * le type de descendant...
  2845.                  *
  2846.                  * Retour par [SOMMAIRE]:
  2847.                  */
  2848.                 CmdList_Replace1Content( pPageArbo_curr -> p_Events, 
  2849.                             FL_SOMM, ACTION_NONE, ACTION_FULLCLS, NULL, pDataPage_parent -> nom );
  2850.         
  2851.                 /*
  2852.                  * Retour par [RETOUR]:
  2853.                  */
  2854.                 switch( n_FnctCurr )
  2855.                 {
  2856.                     case    FA_MENU:
  2857.                     case    FA_DOWNLOAD:
  2858.                         CmdList_Replace1Content( pPageArbo_curr -> p_Events, 
  2859.                                 FL_RETOUR, ACTION_NONE, ACTION_FULLCLS, NULL, pDataPage_parent -> nom );
  2860.                 }
  2861.         
  2862.                 /*
  2863.                  * Retour par [ENVOI]:
  2864.                  */
  2865.                 switch( n_FnctCurr )
  2866.                 {
  2867.                     case    FA_ECRI_MSG:
  2868.                     case    FA_NEW_ACCOUNT:
  2869.                         CmdList_Replace1Content( pPageArbo_curr -> p_Events, 
  2870.                                 FL_ENVOI, ACTION_NONE, ACTION_FULLCLS, NULL, pDataPage_parent -> nom );
  2871.                 }
  2872.  
  2873.                 /*
  2874.                  * Retour par [ANNULATION]:
  2875.                  */
  2876.                 switch( n_FnctCurr )
  2877.                 {
  2878.                     case    FA_DOWNLOAD:
  2879.                         CmdList_Replace1Content( pPageArbo_curr -> p_Events, 
  2880.                                 FL_ANNUL, ACTION_NONE, ACTION_FULLCLS, NULL, pDataPage_parent -> nom );
  2881.                 }
  2882.         }
  2883.  
  2884.         /*
  2885.          * -----------------------------------
  2886.          * Lien du parent vers son d‚scendant:
  2887.          * -----------------------------------
  2888.          * D‚pend du parent:
  2889.          */
  2890.         switch( n_FnctParent )
  2891.         {
  2892.             case    FA_LECT_MSG:
  2893.             case    FA_ECRI_MSG:
  2894.             case    FA_ID:
  2895.             case    FA_NEW_ACCOUNT:
  2896.                 /*
  2897.                  * Lien par ENVOI:
  2898.                  */
  2899.                 CmdList_Replace1Content( pPageArbo_parent -> p_Events, 
  2900.                         FL_ENVOI, ACTION_NONE, ACTION_FULLCLS, NULL, pDataPage_curr -> nom );
  2901.                 break;
  2902.  
  2903.             case    FA_LIST:
  2904.                 /*
  2905.                  * Lien par "Visu S‚lection":
  2906.                  */
  2907.                 if( n_FnctCurr == FA_LECT_MSG )
  2908.                 {
  2909.                     CmdList_Replace1Content( pPageArbo_parent -> p_Events, 
  2910.                         FL_WATCH, ACTION_NONE, ACTION_FULLCLS, NULL, pDataPage_curr -> nom );
  2911.                 }
  2912.                 break;
  2913.  
  2914.             case    FA_FILESEL:
  2915.                 /*
  2916.                  * Lien par "Download S‚lection":
  2917.                  */
  2918.                 if( n_FnctCurr == FA_DOWNLOAD )
  2919.                 {
  2920.                     CmdList_Replace1Content( pPageArbo_parent -> p_Events, 
  2921.                         FL_DOWNLOAD, ACTION_NONE, ACTION_FULLCLS, NULL, pDataPage_curr -> nom );
  2922.                 }
  2923.                 break;
  2924.  
  2925.             case    FA_MENU:
  2926.             case    FA_DOWNLOAD:
  2927.                 /*
  2928.                  * Ajoute un mot clef:
  2929.                  */
  2930.                 break;
  2931.         }
  2932.         
  2933.     }
  2934.     else if( u_ParentCell & CT_INOUT )
  2935.     {    /*
  2936.           * Si le parent est "IN": 
  2937.          * 
  2938.          * Lien 1stpage -> curr
  2939.           */
  2940.         CmdList_Replace1Content( datadir -> dir_spec -> liens_in, 
  2941.                         FL_FIRST, ACTION_NONE, ACTION_NONE, NULL, pDataPage_curr -> nom );
  2942.     }
  2943.  
  2944.  
  2945.     /*
  2946.      * --------------------
  2947.      * Parcourt les liens en descendant … la recherche
  2948.      * de tous les descendants de l'ancˆtre: 
  2949.      */
  2950.     /* find_children( datadir, ascent_x, ascent_y ); */
  2951.  
  2952. }
  2953.  
  2954.  
  2955.  
  2956. /*
  2957.  * find_ascent(-)
  2958.  *
  2959.  * Purpose:
  2960.  * --------
  2961.  * Trouve l'ancˆtre d'une page arbo
  2962.  *
  2963.  * History:
  2964.  * --------
  2965.  * 1993: fplanque: Created
  2966.  * 10.10.94: fplanque: prise en compte cases vides
  2967.  * 17.12.94: retourne cellule parent, traitement sur le parent pris en charge par l'appellant
  2968.  */
  2969. unsigned    find_ascent(                     /* Out: Contenu de la cellule parent */
  2970.                 DATADIR *    datadir,     /* In:  Dossier dans lequel on cherche */
  2971.                 int             pos_x,         /* In:  Position de l'enfant */
  2972.                 int             pos_y, 
  2973.                 int *            ascent_x,     /* Out: Position du parent (meme si case vide) */
  2974.                 int *            ascent_y )
  2975. {
  2976.     /*
  2977.      * Variables: 
  2978.      */
  2979.     DIRSPEC    *    pDirSpec = datadir -> dir_spec;
  2980.     unsigned        map_width = (pDirSpec -> dir_map)[ 0 ];
  2981.     unsigned    *    dir_map    = &(pDirSpec -> dir_map)[ 2 ];
  2982.     unsigned        curr_link;
  2983.  
  2984.     /*
  2985.      * Positionne sur lien pr‚c‚dent la page courante: 
  2986.      */
  2987.     pos_y --;
  2988.     
  2989.     /*
  2990.      * Parcourt les liens … l'envers jusqu'au parent: 
  2991.      */
  2992.     while
  2993.     (
  2994.         curr_link = dir_map[ pos_y * map_width + pos_x ],
  2995.         ((curr_link & (CT_ARBO|CT_INOUT)) == 0) 
  2996.         &&    curr_link != 0
  2997.         && (pos_x >= 0) && (pos_y >= 0)  /* Anti bug */
  2998.     )
  2999.     {    /*
  3000.          * Tant qu'on est sur un lien: 
  3001.          */
  3002.         /* printf("Lien pr‚c‚dent: %d %d  %X\n", pos_x, pos_y, curr_link); */
  3003.         
  3004.         /*
  3005.          * Analyse d'o— vient le lien:
  3006.          * ON CONSIDERE QU'IL N'Y A QU'UN SEUL "IN": 
  3007.          */
  3008.         if ( curr_link & IN_NORTH )
  3009.             pos_y --;        /* Remonte */
  3010.         else if ( curr_link & IN_WEST )
  3011.             pos_x --;        /* Retourne … gauche */
  3012.         else if ( curr_link & IN_EAST )
  3013.             pos_x ++;        /* Retourne … droite */
  3014.         else
  3015.             signale("Lien inconnu!");
  3016.     }
  3017.  
  3018.     /*
  3019.      * Fixe les coordonn‚es de l'ancˆtre: 
  3020.      */
  3021.     *ascent_x = pos_x;
  3022.     *ascent_y = pos_y;
  3023.  
  3024.     /* printf("PARENT: %d %d  %X\n", pos_x, pos_y, curr_link); */
  3025.  
  3026.     return    curr_link;
  3027. }
  3028.  
  3029.  
  3030.  
  3031. /*
  3032.  * find_children(-)
  3033.  *
  3034.  * Purpose:
  3035.  * --------
  3036.  * Trouve les descendants d'une page arbo
  3037.  *
  3038.  * History:
  3039.  * --------
  3040.  * 1993: fplanque: Created
  3041.  */
  3042. void    find_children( 
  3043.             DATADIR *datadir, 
  3044.             int pos_x, 
  3045.             int pos_y )
  3046. {
  3047.     DIRSPEC    *    pDirSpec = datadir -> dir_spec;
  3048.  
  3049.     M_walker_datadir    = datadir;    /* Fixe variable globale */
  3050.     M_walker_mapwidth    = pDirSpec -> dir_map[0];
  3051.     M_walker_map        = &(pDirSpec -> dir_map[2]);
  3052.  
  3053.     walk_arbotree( pos_x, pos_y+1 );
  3054. }
  3055.  
  3056.  
  3057.  
  3058.  
  3059. /*
  3060.  * walk_arbotree(-)
  3061.  *
  3062.  * Purpose:
  3063.  * --------
  3064.  * Descend toutes les branches d'une arbo a partir d'une
  3065.  * position donnée
  3066.  *
  3067.  * History:
  3068.  * --------
  3069.  * 1993: fplanque: Created
  3070.  */
  3071. void    walk_arbotree( int pos_x, int pos_y )
  3072. {
  3073.     unsigned    curr_link;
  3074.     int        nb_branches;        /* Nombre de branches */
  3075.     int        last_x, last_y;
  3076.     
  3077.     
  3078.     /*
  3079.      * Compte nombre de branches: 
  3080.      */
  3081.     do
  3082.     {
  3083.         curr_link = M_walker_map[ pos_y * M_walker_mapwidth + pos_x ];
  3084.         /*    printf("Lien: %X \n", curr_link ); */
  3085.         last_x = pos_x;
  3086.         last_y = pos_y;
  3087.         nb_branches = 0;
  3088.  
  3089.         /*
  3090.          * Teste si on est arriv‚ sur une page ou OUT: 
  3091.          */
  3092.         if( curr_link & (CT_ARBO|CT_INOUT) )
  3093.         {
  3094.             /* printf("Terminaison: "); */
  3095.  
  3096.             if ( curr_link & CT_ARBO )
  3097.             {    /* Si on a trouv‚ un enfant: */
  3098.                 DATAPAGE *child_page = find_arbo_by_xy( M_walker_datadir, pos_x, pos_y );    /* Trouve l'enfant */
  3099.                 /* printf("Enfant: %s \n", child_page -> nom ); */
  3100.                 FAKE_USE( child_page );
  3101.             }
  3102.             else if ( curr_link & CT_INOUT )
  3103.             {    /* Si on a trouv‚ un "OUT": */
  3104.                 /* printf("'OU'\n"); */
  3105.             }
  3106.             break;        /* On arrˆte la recherche */
  3107.         }
  3108.         
  3109.         /*
  3110.          * Teste lien vers la gauche: 
  3111.          */
  3112.         if ( curr_link & OUT_WEST )
  3113.         {
  3114.             nb_branches ++;
  3115.             pos_x --;            /* Si une seule branche, ce sera … gauche */
  3116.         }
  3117.         
  3118.         /*
  3119.          * Teste lien vers le bas: 
  3120.          */
  3121.         if ( curr_link & OUT_SOUTH )
  3122.         {
  3123.             nb_branches ++;
  3124.             pos_y ++;            /* Si une seule branche, ce sera en bas */
  3125.         }
  3126.         
  3127.         /*
  3128.          * Teste lien vers la droite: 
  3129.          */
  3130.         if ( curr_link & OUT_EAST )
  3131.         {
  3132.             nb_branches ++;
  3133.             pos_x ++;            /* Si une seule branche, ce sera … doite */
  3134.         }
  3135.     }
  3136.     while( nb_branches == 1 );        /* Jusqu'… 1 Fourche ou case vide */
  3137.  
  3138.     /*
  3139.      * Teste si on est sur une fourche: 
  3140.      */
  3141.     if ( nb_branches > 1 )
  3142.     {    /* Si on est sur une fourche: */
  3143.         /*    printf("Fourche! "); */
  3144.         /* On va parcourir les branches une … une: */
  3145.         if ( curr_link & OUT_WEST )
  3146.             walk_arbotree( last_x -1 , last_y );    /* R‚cursion */
  3147.  
  3148.         if ( curr_link & OUT_SOUTH )
  3149.             walk_arbotree( last_x , last_y +1 );    /* R‚cursion */
  3150.  
  3151.         if ( curr_link & OUT_EAST )
  3152.             walk_arbotree( last_x +1 , last_y );    /* R‚cursion */
  3153.         
  3154.     }
  3155. }
  3156.  
  3157.  
  3158.  
  3159. /*
  3160.  * free_specialpar(-)
  3161.  *
  3162.  * Purpose:
  3163.  * --------
  3164.  * Efface les paramŠtres sp‚ciaux d'une pge arbo
  3165.  *
  3166.  * History:
  3167.  * --------
  3168.  * 10.05.94: fplanque: Created
  3169.  * 27.03.95: libŠre params FILESEL
  3170.  * 09.04.95: passage union par adresse pour ‚viter warning
  3171.  */
  3172. void    free_specialpar( 
  3173.             int                    n_fnct,                /* Type de page */
  3174.             ARBO_SPECIALPAR *    special_par )
  3175. {
  3176.     if( special_par -> data != NULL )
  3177.     {
  3178.         switch( n_fnct )
  3179.         {
  3180.             case    FA_FILESEL:
  3181.                 free_String( special_par -> filesel -> pMsz_RootPath );
  3182.                 break;
  3183.         }
  3184.  
  3185.         FREE( special_par -> data );
  3186.     }
  3187. }
  3188.  
  3189.